From a2d20cf1f2e1d06c2a14d34f1ffa778596197036 Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Tue, 16 Nov 2021 11:16:04 +0100 Subject: [PATCH] Remove Modelica ModelicaExternalC from 3rdParty. - It is moved to `OpenModelica/OMCompiler/SimulationRuntime` instead. - The reason for this change is that ModelicaExternalC actually depends on out OpenModelicaRuntimeC library for some definitions. As opposed to we depending on it as every other 3rdParty library. It has an API we have to implement. Not just something we consume. So to keep the hierarchy and structure as logical as possible AND to make sure build tools can link libraries in the correct order without us having to interfere and reorder things, it is being moved. --- .gitignore | 24 - CMakeLists.txt | 9 - ModelicaExternalC.txt | 27 - ModelicaExternalC/.gitattributes | 1 - .../BuildProjects/autotools/Makefile.am | 18 - .../BuildProjects/autotools/README | 21 - .../BuildProjects/autotools/autogen.sh | 7 - .../BuildProjects/autotools/configure.ac | 181 - ModelicaExternalC/C-Sources/ModelicaFFT.c | 569 - ModelicaExternalC/C-Sources/ModelicaFFT.h | 75 - ModelicaExternalC/C-Sources/ModelicaIO.c | 1339 -- ModelicaExternalC/C-Sources/ModelicaIO.h | 176 - .../C-Sources/ModelicaInternal.c | 1383 -- .../C-Sources/ModelicaInternal.h | 122 - ModelicaExternalC/C-Sources/ModelicaMatIO.c | 15833 ---------------- ModelicaExternalC/C-Sources/ModelicaMatIO.h | 462 - ModelicaExternalC/C-Sources/ModelicaRandom.c | 429 - ModelicaExternalC/C-Sources/ModelicaRandom.h | 85 - .../C-Sources/ModelicaStandardTables.c | 7392 -------- .../C-Sources/ModelicaStandardTables.h | 499 - .../C-Sources/ModelicaStandardTablesUsertab.c | 63 - ModelicaExternalC/C-Sources/ModelicaStrings.c | 540 - ModelicaExternalC/C-Sources/ModelicaStrings.h | 104 - .../C-Sources/ModelicaUtilities.h | 208 - ModelicaExternalC/C-Sources/gconstructor.h | 124 - ModelicaExternalC/C-Sources/read_data_impl.h | 596 - ModelicaExternalC/C-Sources/readme.txt | 56 - ModelicaExternalC/C-Sources/safe-math.h | 1078 -- ModelicaExternalC/C-Sources/snprintf.c | 1572 -- ModelicaExternalC/C-Sources/stdint_msvc.h | 259 - ModelicaExternalC/C-Sources/stdint_wrap.h | 98 - ModelicaExternalC/C-Sources/uthash.h | 1136 -- ModelicaExternalC/C-Sources/win32_dirent.c | 323 - ModelicaExternalC/C-Sources/win32_dirent.h | 89 - ModelicaExternalC/C-Sources/zlib/ChangeLog | 1515 -- ModelicaExternalC/C-Sources/zlib/FAQ | 368 - ModelicaExternalC/C-Sources/zlib/README | 115 - ModelicaExternalC/C-Sources/zlib/adler32.c | 186 - ModelicaExternalC/C-Sources/zlib/compress.c | 86 - ModelicaExternalC/C-Sources/zlib/crc32.c | 442 - ModelicaExternalC/C-Sources/zlib/crc32.h | 441 - ModelicaExternalC/C-Sources/zlib/deflate.c | 2163 --- ModelicaExternalC/C-Sources/zlib/deflate.h | 349 - ModelicaExternalC/C-Sources/zlib/gzclose.c | 25 - ModelicaExternalC/C-Sources/zlib/gzguts.h | 221 - ModelicaExternalC/C-Sources/zlib/gzlib.c | 637 - ModelicaExternalC/C-Sources/zlib/gzread.c | 654 - ModelicaExternalC/C-Sources/zlib/gzwrite.c | 665 - ModelicaExternalC/C-Sources/zlib/infback.c | 640 - ModelicaExternalC/C-Sources/zlib/inffast.c | 323 - ModelicaExternalC/C-Sources/zlib/inffast.h | 11 - ModelicaExternalC/C-Sources/zlib/inffixed.h | 94 - ModelicaExternalC/C-Sources/zlib/inflate.c | 1561 -- ModelicaExternalC/C-Sources/zlib/inflate.h | 125 - ModelicaExternalC/C-Sources/zlib/inftrees.c | 304 - ModelicaExternalC/C-Sources/zlib/inftrees.h | 62 - ModelicaExternalC/C-Sources/zlib/trees.c | 1203 -- ModelicaExternalC/C-Sources/zlib/trees.h | 128 - ModelicaExternalC/C-Sources/zlib/uncompr.c | 93 - ModelicaExternalC/C-Sources/zlib/zconf.h | 534 - ModelicaExternalC/C-Sources/zlib/zlib.h | 1912 -- ModelicaExternalC/C-Sources/zlib/zutil.c | 325 - ModelicaExternalC/C-Sources/zlib/zutil.h | 271 - ModelicaExternalC/CMakeLists.txt | 81 - 64 files changed, 50432 deletions(-) delete mode 100644 ModelicaExternalC.txt delete mode 100644 ModelicaExternalC/.gitattributes delete mode 100644 ModelicaExternalC/BuildProjects/autotools/Makefile.am delete mode 100644 ModelicaExternalC/BuildProjects/autotools/README delete mode 100755 ModelicaExternalC/BuildProjects/autotools/autogen.sh delete mode 100644 ModelicaExternalC/BuildProjects/autotools/configure.ac delete mode 100644 ModelicaExternalC/C-Sources/ModelicaFFT.c delete mode 100644 ModelicaExternalC/C-Sources/ModelicaFFT.h delete mode 100644 ModelicaExternalC/C-Sources/ModelicaIO.c delete mode 100644 ModelicaExternalC/C-Sources/ModelicaIO.h delete mode 100644 ModelicaExternalC/C-Sources/ModelicaInternal.c delete mode 100644 ModelicaExternalC/C-Sources/ModelicaInternal.h delete mode 100644 ModelicaExternalC/C-Sources/ModelicaMatIO.c delete mode 100644 ModelicaExternalC/C-Sources/ModelicaMatIO.h delete mode 100644 ModelicaExternalC/C-Sources/ModelicaRandom.c delete mode 100644 ModelicaExternalC/C-Sources/ModelicaRandom.h delete mode 100644 ModelicaExternalC/C-Sources/ModelicaStandardTables.c delete mode 100644 ModelicaExternalC/C-Sources/ModelicaStandardTables.h delete mode 100644 ModelicaExternalC/C-Sources/ModelicaStandardTablesUsertab.c delete mode 100644 ModelicaExternalC/C-Sources/ModelicaStrings.c delete mode 100644 ModelicaExternalC/C-Sources/ModelicaStrings.h delete mode 100644 ModelicaExternalC/C-Sources/ModelicaUtilities.h delete mode 100644 ModelicaExternalC/C-Sources/gconstructor.h delete mode 100644 ModelicaExternalC/C-Sources/read_data_impl.h delete mode 100644 ModelicaExternalC/C-Sources/readme.txt delete mode 100644 ModelicaExternalC/C-Sources/safe-math.h delete mode 100644 ModelicaExternalC/C-Sources/snprintf.c delete mode 100644 ModelicaExternalC/C-Sources/stdint_msvc.h delete mode 100644 ModelicaExternalC/C-Sources/stdint_wrap.h delete mode 100644 ModelicaExternalC/C-Sources/uthash.h delete mode 100644 ModelicaExternalC/C-Sources/win32_dirent.c delete mode 100644 ModelicaExternalC/C-Sources/win32_dirent.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/ChangeLog delete mode 100644 ModelicaExternalC/C-Sources/zlib/FAQ delete mode 100644 ModelicaExternalC/C-Sources/zlib/README delete mode 100644 ModelicaExternalC/C-Sources/zlib/adler32.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/compress.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/crc32.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/crc32.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/deflate.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/deflate.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/gzclose.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/gzguts.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/gzlib.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/gzread.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/gzwrite.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/infback.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/inffast.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/inffast.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/inffixed.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/inflate.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/inflate.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/inftrees.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/inftrees.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/trees.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/trees.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/uncompr.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/zconf.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/zlib.h delete mode 100644 ModelicaExternalC/C-Sources/zlib/zutil.c delete mode 100644 ModelicaExternalC/C-Sources/zlib/zutil.h delete mode 100644 ModelicaExternalC/CMakeLists.txt diff --git a/.gitignore b/.gitignore index ec10955d4..e35ce5038 100644 --- a/.gitignore +++ b/.gitignore @@ -83,30 +83,6 @@ Ipopt-3.13.4/build FMIL/build/ FMIL/install/ -ModelicaExternalC/BuildProjects/autotools/.libs/ -ModelicaExternalC/BuildProjects/autotools/AUTHORS -ModelicaExternalC/BuildProjects/autotools/COPYING -ModelicaExternalC/BuildProjects/autotools/ChangeLog -ModelicaExternalC/BuildProjects/autotools/INSTALL -ModelicaExternalC/BuildProjects/autotools/Makefile -ModelicaExternalC/BuildProjects/autotools/Makefile.in -ModelicaExternalC/BuildProjects/autotools/NEWS -ModelicaExternalC/BuildProjects/autotools/aclocal.m4 -ModelicaExternalC/BuildProjects/autotools/compile -ModelicaExternalC/BuildProjects/autotools/config.guess -ModelicaExternalC/BuildProjects/autotools/config.sub -ModelicaExternalC/BuildProjects/autotools/configure -ModelicaExternalC/BuildProjects/autotools/depcomp -ModelicaExternalC/BuildProjects/autotools/install-sh -ModelicaExternalC/BuildProjects/autotools/libtool -ModelicaExternalC/BuildProjects/autotools/ltmain.sh -ModelicaExternalC/BuildProjects/autotools/m4/ -ModelicaExternalC/BuildProjects/autotools/missing -ModelicaExternalC/C-Sources/.deps/ -ModelicaExternalC/C-Sources/.dirstamp -ModelicaExternalC/C-Sources/zlib/.deps/ -ModelicaExternalC/C-Sources/zlib/.dirstamp - SuiteSparse/build/ antlr/3.2/libantlr3c-3.2/.deps/ diff --git a/CMakeLists.txt b/CMakeLists.txt index eef86eedd..c8497d8d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,15 +131,6 @@ add_library(omc::3rd::metis ALIAS metis) target_include_directories(metis INTERFACE metis-5.1.0/include) -# ModelicaExternalC -omc_add_subdirectory(ModelicaExternalC) -add_library(omc::3rd::Modelica::ExternalC ALIAS ModelicaExternalC) -add_library(omc::3rd::Modelica::MatIO ALIAS ModelicaMatIO) -add_library(omc::3rd::Modelica::IO ALIAS ModelicaIO) -add_library(omc::3rd::Modelica::StandardTables ALIAS ModelicaStandardTables) -add_library(omc::3rd::Modelica::zlib ALIAS zlib) - - omc_add_subdirectory(open62541) add_library(omc::3rd::opcua ALIAS opcua) diff --git a/ModelicaExternalC.txt b/ModelicaExternalC.txt deleted file mode 100644 index 4cb04ae82..000000000 --- a/ModelicaExternalC.txt +++ /dev/null @@ -1,27 +0,0 @@ -export GUSER=sjoelund - -# make an empty git repo -git init -git remote add origin git@github.com:${GUSER}/MSL-split -git remote add MSL git@github.com:modelica/Modelica.git -git fetch MSL master -git checkout -f MSL/master -git subtree split --squash --prefix="Modelica/Resources/C-Sources" -b MSL_sources -git subtree split --squash --prefix="Modelica/Resources/BuildProjects/autotools" -b MSL_autotools - -# if you haven't forked it already fork it in your ${GUSER} from: -# https://github.com/sjoelund/MSL-split -# https://github.com/adrpo/MSL-split -git push -u origin MSL/master:MSL_master -git push -u origin MSL_sources -git push -u origin MSL_autotools - -# In OMCompiler/3rdParty - -# if you haven't added it yet, add it: -git subtree add --squash --prefix="ModelicaExternalC/C-Sources" git@github.com:${GUSER}/MSL-split MSL_sources -git subtree add --squash --prefix="ModelicaExternalC/BuildProjects/autotools" git@github.com:${GUSER}/MSL-split MSL_autotools - -# if is already added, just pull it over: -git subtree pull --squash --prefix="ModelicaExternalC/C-Sources" git@github.com:${GUSER}/MSL-split MSL_sources -git subtree pull --squash --prefix="ModelicaExternalC/BuildProjects/autotools" git@github.com:${GUSER}/MSL-split MSL_autotools diff --git a/ModelicaExternalC/.gitattributes b/ModelicaExternalC/.gitattributes deleted file mode 100644 index 176a458f9..000000000 --- a/ModelicaExternalC/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* text=auto diff --git a/ModelicaExternalC/BuildProjects/autotools/Makefile.am b/ModelicaExternalC/BuildProjects/autotools/Makefile.am deleted file mode 100644 index cd26c6dbe..000000000 --- a/ModelicaExternalC/BuildProjects/autotools/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -lib_LTLIBRARIES = libzlib.la libModelicaExternalC.la libModelicaMatIO.la libModelicaIO.la libModelicaStandardTables.la -libModelicaExternalC_la_SOURCES = ../../C-Sources/ModelicaFFT.c ../../C-Sources/ModelicaInternal.c ../../C-Sources/ModelicaRandom.c ../../C-Sources/ModelicaStrings.c -libModelicaExternalC_la_LIBADD = @LIBMATH@ -libModelicaIO_la_SOURCES = ../../C-Sources/ModelicaIO.c -libModelicaIO_la_LIBADD = libModelicaMatIO.la -libModelicaMatIO_la_SOURCES = ../../C-Sources/ModelicaMatIO.c ../../C-Sources/snprintf.c -libModelicaStandardTables_la_SOURCES = ../../C-Sources/ModelicaStandardTables.c ../../C-Sources/ModelicaStandardTablesUsertab.c -libModelicaStandardTables_la_LIBADD = libModelicaMatIO.la @LIBMATH@ - -# If the OS does not have zlib available, compile it and include it together with libModelicaStandardTables -if INCLUDEZLIB -libzlib_la_SOURCES = ../../C-Sources/zlib/adler32.c ../../C-Sources/zlib/compress.c ../../C-Sources/zlib/crc32.c ../../C-Sources/zlib/deflate.c ../../C-Sources/zlib/gzclose.c ../../C-Sources/zlib/gzlib.c ../../C-Sources/zlib/gzread.c ../../C-Sources/zlib/gzwrite.c ../../C-Sources/zlib/infback.c ../../C-Sources/zlib/inffast.c ../../C-Sources/zlib/inflate.c ../../C-Sources/zlib/inftrees.c ../../C-Sources/zlib/trees.c ../../C-Sources/zlib/uncompr.c ../../C-Sources/zlib/zutil.c -libModelicaMatIO_la_LIBADD = libzlib.la @LIBZLIB@ @LIBHDF5@ -else -libModelicaMatIO_la_LIBADD = @LIBZLIB@ @LIBHDF5@ -endif -libModelicaMatIO_la_LIBADD = @LIBHDF5@ -libzlib_la_LIBADD = @LIBZLIB@ diff --git a/ModelicaExternalC/BuildProjects/autotools/README b/ModelicaExternalC/BuildProjects/autotools/README deleted file mode 100644 index 60354044b..000000000 --- a/ModelicaExternalC/BuildProjects/autotools/README +++ /dev/null @@ -1,21 +0,0 @@ -For more detailed installation instructions: -./autogen.sh (generates the project) -less INSTALL -# Default: Build only shared library with as much included as possible. Adds static zlib if not found in the system. -./configure -# To add static libraries (not as compatible) -./configure --enable-static -# For a static library similar to the Windows build -./configure --disable-hdf5 --enable-static-zlib --enable-static --disable-shared --libdir=/path/to/Modelica/Resources/Library/linux64 -make -sudo make install -sudo make uninstall - -Note that special care has to be taken if there is a space in the path (e.g. /path/to/Modelica 3.2.3/Resources/Library/linux32). -GNU tools, libtool in particular, cannot handle paths with spaces in them (which is one of the reasons you should never install MinGW in a path with spaces). -In this case, there are two main workarounds: -* Temporarily move the directory to one without spaces, and moving it back after make install. -* Manually copying the files instead of make install: cp .libs/* ../Library/linux32 - -Minimal files needed to compile on Unix (requires autotools installed): - autogen.sh, configure.ac, Makefile.am, README diff --git a/ModelicaExternalC/BuildProjects/autotools/autogen.sh b/ModelicaExternalC/BuildProjects/autotools/autogen.sh deleted file mode 100755 index c2deb41e4..000000000 --- a/ModelicaExternalC/BuildProjects/autotools/autogen.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -# Not a proper package; will be added somewhere else anyway -mkdir -p m4 # Needed in OSX -for f in AUTHORS ChangeLog COPYING README NEWS; do - test -f "$f" || touch "$f" -done -autoreconf --force --install diff --git a/ModelicaExternalC/BuildProjects/autotools/configure.ac b/ModelicaExternalC/BuildProjects/autotools/configure.ac deleted file mode 100644 index 4f46e5705..000000000 --- a/ModelicaExternalC/BuildProjects/autotools/configure.ac +++ /dev/null @@ -1,181 +0,0 @@ -dnl Init -AC_PREREQ([2.63]) -AC_INIT([Modelica Standard Library Tables],[4.0.0],[https://github.com/modelica/ModelicaStandardLibrary],[libmodelicastandardtables],[https://modelica.org]) - -AM_INIT_AUTOMAKE([subdir-objects]) -AC_CONFIG_MACRO_DIR([m4]) - -AC_LANG([C]) -AC_PROG_CC -AC_PROG_CPP -AC_PROG_MAKE_SET -LT_INIT([disable-static]) -AC_SUBST(LIBZLIB) -AC_SUBST(LIBHDF5) -AC_SUBST(LIBMATH) -dnl Check for HDF5, etc - -LIBS_BEFORE="$LIBS" -LIBS="" -AC_SEARCH_LIBS([atan2], [m], [LIBMATH="$LIBS"], [ - AC_MSG_ERROR([unable to find the atan2() function]) -]) -LIBS="$LIBS_BEFORE" - -AC_DEFUN([C_FLAG_CHECK_AND_ADD], -[dnl - AC_MSG_CHECKING([if $CC supports $1]) - AC_LANG_PUSH([C]) - ac_saved_cflags="$CFLAGS" - CFLAGS="-Werror $1" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], - [AC_MSG_RESULT([yes]) ; CFLAGS="$ac_saved_cflags $1"], - [AC_MSG_RESULT([no]) ; CFLAGS="$ac_saved_cflags"] - ) - AC_LANG_POP([C]) -]) - -C_FLAG_CHECK_AND_ADD([-fno-delete-null-pointer-checks]) -C_FLAG_CHECK_AND_ADD([-Werror=implicit-function-declaration]) - -AC_SEARCH_LIBS([floor],[m]) - -LIBS_BEFORE="$LIBS" -ZLIB="Yes" -STATIC_ZLIB="No" -DUMMY_USERTAB="" -AC_ARG_ENABLE(hdf5, - [ --enable-hdf5[=yes] Adds support for HDF5 and MAT7.3 formats],[test "xno" = x"$enableval" && HDF5="No"],[HDF5="Yes"]) -AC_ARG_ENABLE(zlib, - [ --enable-zlib[=yes] Adds support for the MAT7 format],[test "xno" = x"$enableval" && ZLIB="No"],[ZLIB="Yes"]) -AC_ARG_ENABLE(shared-tables, - [ --enable-shared-tables[=yes] Adds support for shared tables, reducing file I/O and reducing memory footprint],[test "xyes" = x"$enableval" && SHARED_TABLES="Yes"],[SHARED_TABLES="Yes"]) -AC_ARG_ENABLE(static-zlib, [ --enable-static-zlib[=no]],[test "xyes" = x"$enableval" && STATIC_ZLIB="Yes"],[STATIC_ZLIB="No"]) - -if test "$ZLIB" = "Yes"; then - AC_CHECK_HEADERS(zlib.h,[AC_SEARCH_LIBS([gzclose], [z], [ZLIB="Yes"], [ZLIB="No"])],[ZLIB="No"]) - if test "$ZLIB" = "No" && test -d ../../C-Sources/zlib; then - ZLIB="Yes, from sources" - else - LIBZLIB="$LIBS" - fi -fi -LIBS="$LIBS_BEFORE" - -AM_CONDITIONAL([INCLUDEZLIB], [test "$ZLIB" = "Yes, from sources" -o "$STATIC_ZLIB" = "Yes"]) - -if test "$ZLIB" = "No" -o "$HDF5" = "No"; then - HDF5="No" -else -AC_CHECK_PROG(MPICC,mpicc,[yes]) -AC_MSG_CHECKING([hdf5.h]) -for HDF_FIRST in Yes No; do - for d in serial mpich openmpi; do - if test -d /usr/include/hdf5/$d; then - CPPFLAGS="$CPPFLAGS -I/usr/include/hdf5/$d" - break - fi - done - AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include ]],[])],AC_MSG_RESULT([OK]),[ - if ! test -z "$MPICC"; then - CPPFLAGS_BAK=$CPPFLAGS - MPI_CPPFLAGS=`OMPI_CC=$CC mpicc -showme:compile` - CPPFLAGS="$CPPFLAGS $MPI_CPPFLAGS" - AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include ]],[])],AC_MSG_RESULT([[OK, needs mpi.h]]),[CPPFLAGS=$CPPFLAGS_BAK; HDF5="No"]) - fi - if test "No" = "$HDF5"; then - HDF5="Yes" - if test "$HDF_FIRST" = "Yes" && test "$host" = "$build" && apt-cache show libhdf5-dev > /dev/null 2>&1; then - HDF5_INSTALL_CMD="apt-get install libhdf5-dev" - if gksudo --description "HDF5 is an optional dependency of ModelicaMatIO used to read/write MATLAB 7.3 files. $HDF5_INSTALL_CMD" $HDF5_INSTALL_CMD; then - continue - else - HDF5="No"; - AC_MSG_RESULT([failed]) - fi - else - HDF5="No"; - AC_MSG_RESULT([failed]) - fi - fi - ]) - break -done -fi - -# Ok, so we have hdf5.h. Now for the fun stuff: -# We need to look for the 1.8 version of the API, but it is not always enabled by default even if the library supports it. -# So we first try to compile as usual. If that does not work, add a whole bunch of compatibility #defines and try again. -if test "$HDF5" = "Yes"; then - -LIBS_BEFORE="$LIBS" -AC_SEARCH_LIBS([H5Eget_auto2],[hdf5 hdf5_serial hdf5_mpich hdf5_openmpi],[HDF5="Yes"],[HDF5="No"]) -AC_MSG_CHECKING([default API version]) -CPPFLAGS_BEFORE="$CPPFLAGS" -FLAGS=`test "$HDF5" = "Yes" && echo 1.8 1.6` -HDF5="No" -for FLAG in $FLAGS; do - if test "$HDF5" = "Yes"; then - break - elif test "$FLAG" = "1.6"; then - CPPFLAGS="$CPPFLAGS -DH5Acreate_vers=2 -DH5Aiterate_vers=2 -DH5Dcreate_vers=2 -DH5Dopen_vers=2 -DH5Eclear_vers=2 -DH5Eprint_vers=2 -DH5Epush_vers=2 -DH5Eset_auto_vers=2 -DH5Eget_auto_vers=2 -DH5Ewalk_vers=2 -DH5Gcreate_vers=2 -DH5Gopen_vers=2 -DH5Pget_filter_vers=2 -DH5Pget_filter_by_id_vers=2 -DH5Pinsert_vers=2 -DH5Pregister_vers=2 -DH5Rget_obj_type_vers=2 -DH5Tarray_create_vers=2 -DH5Tcommit_vers=2 -DH5Tget_array_dims_vers=2 -DH5Topen_vers=2"; - fi - AC_TRY_LINK([ -#include -#include -#include ], -[H5Eget_auto(0,NULL,NULL)], -[HDF5="Yes";AC_MSG_RESULT([$FLAG]);break], -[CPPFLAGS=$CPPFLAGS_BEFORE]) -done - -if test "$HDF5" = "No"; then - AC_MSG_RESULT([1.8 API not available]) -else - LIBHDF5="$LIBS" -fi -LIBS=$LIBS_BEFORE - -fi - -AC_CHECK_HEADERS(dirent.h,[],[CPPFLAGS="$CPPFLAGS -DNO_FILE_SYSTEM"]) -AC_CHECK_HEADERS(locale.h,[],[CPPFLAGS="$CPPFLAGS -DNO_LOCALE"]) -AC_CHECK_HEADERS(time.h,[],[CPPFLAGS="$CPPFLAGS -DNO_TIME"]) -AC_MSG_CHECKING([for getpid()]) -AC_TRY_LINK([ -#include -], -[getpid();], -[AC_MSG_RESULT([yes])], -[AC_MSG_RESULT([no]); CPPFLAGS="$CPPFLAGS -DNO_PID"]) - -AC_ARG_ENABLE(dummy-usertab, [ --disable-dummy-usertab[=no] Skips generation of the dummy usertab function],[ - if test "xyes" = x"$enableval"; then - DUMMY_USERTAB="yes" - fi -],[DUMMY_USERTAB="yes"]) -if test "yes" = "$DUMMY_USERTAB"; then - CPPFLAGS="$CPPFLAGS -DDUMMY_FUNCTION_USERTAB=1" - STATIC_CPPFLAGS="$CPPFLAGS -DDUMMY_FUNCTION_USERTAB=1" -fi -if test "$ZLIB" = "Yes"; then -CPPFLAGS="$CPPFLAGS -DHAVE_ZLIB=1" -fi -if test "$HDF5" = "Yes"; then -CPPFLAGS="$CPPFLAGS -DHAVE_HDF5=1" -fi -if test "$SHARED_TABLES" = "Yes"; then -CPPFLAGS="$CPPFLAGS -DTABLE_SHARE=1" -fi - -echo "ModelicaMatIO may use ZLIB: $ZLIB" -echo "ModelicaMatIO may use HDF5: $HDF5" -echo "ModelicaMatIO may use MAT7.3: $HDF5" - -if test "$libdir" = '${exec_prefix}/lib'; then - # It is hard to detect where to put the libraries if we cross-compile. Let the tool decide where to put it. - # Use Resources/Library/ as the default. - libdir=`pwd`/../../Library/ -fi - -AC_OUTPUT([Makefile]) diff --git a/ModelicaExternalC/C-Sources/ModelicaFFT.c b/ModelicaExternalC/C-Sources/ModelicaFFT.c deleted file mode 100644 index d44c3608b..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaFFT.c +++ /dev/null @@ -1,569 +0,0 @@ -/* ModelicaFFT.c - FFT functions - - Copyright (C) 2015-2020, Modelica Association and contributors - Copyright (C) 2003-2010, Mark Borgerding - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* Adapted to the needs of the Modelica Standard Library: - - Changelog: - Dec. 02, 2015: by Martin Otter, DLR - Combined the C- and Header files of Kiss-FFT as needed for MSL - Adapted the memory allocation scheme so that for exponents of 2,3,5 - memory has to be provided from the calling function - (for if length of vector is not a multiple of 2,3,5, the function - allocates additional memory, whenever it is called, and frees it before - the function is left) -*/ - -#include "ModelicaFFT.h" -#include -#include -#include - -#define MRKISS_FFT_TMP_ALLOC malloc -#define MRKISS_FFT_TMP_FREE free - -#define mrkiss_fft_scalar double -#define MAXFACTORS 32 -/* e.g. an fft of length 128 has 4 factors - as far as kissfft is concerned - 4*4*4*2 -*/ - -typedef struct { - mrkiss_fft_scalar r; - mrkiss_fft_scalar i; -} mrkiss_fft_cpx; - -struct mrkiss_fft_state { - int nfft; - int inverse; - int factors[2*MAXFACTORS]; - mrkiss_fft_cpx *twiddles; /* twiddles[nfft] */ -}; -typedef struct mrkiss_fft_state* mrkiss_fft_cfg; - -struct mrkiss_fftr_state { - mrkiss_fft_cfg substate; - mrkiss_fft_cpx * tmpbuf; - mrkiss_fft_cpx * super_twiddles; -}; -typedef struct mrkiss_fftr_state* mrkiss_fftr_cfg; - -/* include from _kiss_fft_guts.h ------------------------------------------ */ - -/* - Explanation of macros dealing with complex math: - - C_MUL(m,a,b) : m = a*b - C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise - C_SUB( res, a,b) : res = a - b - C_SUBFROM( res , a) : res -= a - C_ADDTO( res , a) : res += a - * */ - -#define S_MUL(a,b) ( (a)*(b) ) -#define C_MUL(m,a,b) \ - do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ - (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) -#define C_FIXDIV(c,div) /* NOOP */ -#define C_MULBYSCALAR( c, s ) \ - do{ (c).r *= (s);\ - (c).i *= (s); }while(0) - -#ifndef CHECK_OVERFLOW_OP -# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ -#endif - -#define C_ADD( res, a,b)\ - do { \ - CHECK_OVERFLOW_OP((a).r,+,(b).r)\ - CHECK_OVERFLOW_OP((a).i,+,(b).i)\ - (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ - }while(0) -#define C_SUB( res, a,b)\ - do { \ - CHECK_OVERFLOW_OP((a).r,-,(b).r)\ - CHECK_OVERFLOW_OP((a).i,-,(b).i)\ - (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ - }while(0) -#define C_ADDTO( res , a)\ - do { \ - CHECK_OVERFLOW_OP((res).r,+,(a).r)\ - CHECK_OVERFLOW_OP((res).i,+,(a).i)\ - (res).r += (a).r; (res).i += (a).i;\ - }while(0) - -#define C_SUBFROM( res , a)\ - do {\ - CHECK_OVERFLOW_OP((res).r,-,(a).r)\ - CHECK_OVERFLOW_OP((res).i,-,(a).i)\ - (res).r -= (a).r; (res).i -= (a).i; \ - }while(0) - -#define MRKISS_FFT_COS(phase) (mrkiss_fft_scalar) cos(phase) -#define MRKISS_FFT_SIN(phase) (mrkiss_fft_scalar) sin(phase) -#define HALF_OF(x) ((x)*.5) - -#define kf_cexp(x,phase) \ - do{ \ - (x)->r = MRKISS_FFT_COS(phase);\ - (x)->i = MRKISS_FFT_SIN(phase);\ - }while(0) - -/* end of include from _kiss_fft_guts.h ------------------------------------------ */ - -/* include of kiss_fft.c -------------------------------------------------------- */ - -static void kf_bfly2( - mrkiss_fft_cpx * Fout, - const size_t fstride, - const mrkiss_fft_cfg st, - int m -) { - mrkiss_fft_cpx * Fout2; - mrkiss_fft_cpx * tw1 = st->twiddles; - mrkiss_fft_cpx t; - Fout2 = Fout + m; - do { - C_FIXDIV(*Fout,2); - C_FIXDIV(*Fout2,2); - - C_MUL (t, *Fout2 , *tw1); - tw1 += fstride; - C_SUB( *Fout2 , *Fout , t ); - C_ADDTO( *Fout , t ); - ++Fout2; - ++Fout; - } while (--m); -} - -static void kf_bfly4( - mrkiss_fft_cpx * Fout, - const size_t fstride, - const mrkiss_fft_cfg st, - const size_t m -) { - mrkiss_fft_cpx *tw1,*tw2,*tw3; - mrkiss_fft_cpx scratch[6]; - size_t k=m; - const size_t m2=2*m; - const size_t m3=3*m; - - tw3 = tw2 = tw1 = st->twiddles; - - do { - C_FIXDIV(*Fout,4); - C_FIXDIV(Fout[m],4); - C_FIXDIV(Fout[m2],4); - C_FIXDIV(Fout[m3],4); - - C_MUL(scratch[0],Fout[m] , *tw1 ); - C_MUL(scratch[1],Fout[m2] , *tw2 ); - C_MUL(scratch[2],Fout[m3] , *tw3 ); - - C_SUB( scratch[5] , *Fout, scratch[1] ); - C_ADDTO(*Fout, scratch[1]); - C_ADD( scratch[3] , scratch[0] , scratch[2] ); - C_SUB( scratch[4] , scratch[0] , scratch[2] ); - C_SUB( Fout[m2], *Fout, scratch[3] ); - tw1 += fstride; - tw2 += fstride*2; - tw3 += fstride*3; - C_ADDTO( *Fout , scratch[3] ); - - if(st->inverse) { - Fout[m].r = scratch[5].r - scratch[4].i; - Fout[m].i = scratch[5].i + scratch[4].r; - Fout[m3].r = scratch[5].r + scratch[4].i; - Fout[m3].i = scratch[5].i - scratch[4].r; - } else { - Fout[m].r = scratch[5].r + scratch[4].i; - Fout[m].i = scratch[5].i - scratch[4].r; - Fout[m3].r = scratch[5].r - scratch[4].i; - Fout[m3].i = scratch[5].i + scratch[4].r; - } - ++Fout; - } while(--k); -} - -static void kf_bfly3( - mrkiss_fft_cpx * Fout, - const size_t fstride, - const mrkiss_fft_cfg st, - size_t m -) { - size_t k=m; - const size_t m2 = 2*m; - mrkiss_fft_cpx *tw1,*tw2; - mrkiss_fft_cpx scratch[5]; - mrkiss_fft_cpx epi3; - epi3 = st->twiddles[fstride*m]; - - tw1=tw2=st->twiddles; - - do { - C_FIXDIV(*Fout,3); - C_FIXDIV(Fout[m],3); - C_FIXDIV(Fout[m2],3); - - C_MUL(scratch[1],Fout[m] , *tw1); - C_MUL(scratch[2],Fout[m2] , *tw2); - - C_ADD(scratch[3],scratch[1],scratch[2]); - C_SUB(scratch[0],scratch[1],scratch[2]); - tw1 += fstride; - tw2 += fstride*2; - - Fout[m].r = Fout->r - HALF_OF(scratch[3].r); - Fout[m].i = Fout->i - HALF_OF(scratch[3].i); - - C_MULBYSCALAR( scratch[0] , epi3.i ); - - C_ADDTO(*Fout,scratch[3]); - - Fout[m2].r = Fout[m].r + scratch[0].i; - Fout[m2].i = Fout[m].i - scratch[0].r; - - Fout[m].r -= scratch[0].i; - Fout[m].i += scratch[0].r; - - ++Fout; - } while(--k); -} - -static void kf_bfly5( - mrkiss_fft_cpx * Fout, - const size_t fstride, - const mrkiss_fft_cfg st, - int m -) { - mrkiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; - int u; - mrkiss_fft_cpx scratch[13]; - mrkiss_fft_cpx * twiddles = st->twiddles; - mrkiss_fft_cpx *tw; - mrkiss_fft_cpx ya,yb; - ya = twiddles[fstride*m]; - yb = twiddles[fstride*2*m]; - - Fout0=Fout; - Fout1=Fout0+m; - Fout2=Fout0+2*m; - Fout3=Fout0+3*m; - Fout4=Fout0+4*m; - - tw=st->twiddles; - for ( u=0; ur += scratch[7].r + scratch[8].r; - Fout0->i += scratch[7].i + scratch[8].i; - - scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); - scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); - - scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); - scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); - - C_SUB(*Fout1,scratch[5],scratch[6]); - C_ADD(*Fout4,scratch[5],scratch[6]); - - scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); - scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); - scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); - scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); - - C_ADD(*Fout2,scratch[11],scratch[12]); - C_SUB(*Fout3,scratch[11],scratch[12]); - - ++Fout0; - ++Fout1; - ++Fout2; - ++Fout3; - ++Fout4; - } -} - -/* perform the butterfly for one stage of a mixed radix FFT */ -static void kf_bfly_generic( - mrkiss_fft_cpx * Fout, - const size_t fstride, - const mrkiss_fft_cfg st, - int m, - int p -) { - int u,q1,q; - mrkiss_fft_cpx * twiddles = st->twiddles; - mrkiss_fft_cpx t; - int Norig = st->nfft; - - mrkiss_fft_cpx * scratch = (mrkiss_fft_cpx*)MRKISS_FFT_TMP_ALLOC(sizeof(mrkiss_fft_cpx)*p); - - for ( u=0; u=Norig) twidx-=Norig; - C_MUL(t,scratch[q] , twiddles[twidx] ); - C_ADDTO( Fout[ k ] ,t); - } - k += m; - } - } - MRKISS_FFT_TMP_FREE(scratch); -} - -static void kf_work( - mrkiss_fft_cpx * Fout, - const mrkiss_fft_cpx * f, - const size_t fstride, - int in_stride, - int * factors, - const mrkiss_fft_cfg st -) { - mrkiss_fft_cpx * Fout_beg=Fout; - const int p=*factors++; /* the radix */ - const int m=*factors++; /* stage's fft length/p */ - const mrkiss_fft_cpx * Fout_end = Fout + p*m; - - if (m==1) { - do { - *Fout = *f; - f += fstride*in_stride; - } while(++Fout != Fout_end ); - } else { - do { - /* recursive call: - DFT of size m*p performed by doing - p instances of smaller DFTs of size m, - each one takes a decimated version of the input */ - kf_work( Fout , f, fstride*p, in_stride, factors,st); - f += fstride*in_stride; - } while( (Fout += m) != Fout_end ); - } - - Fout=Fout_beg; - - /* recombine the p smaller DFTs */ - switch (p) { - case 2: - kf_bfly2(Fout,fstride,st,m); - break; - case 3: - kf_bfly3(Fout,fstride,st,m); - break; - case 4: - kf_bfly4(Fout,fstride,st,m); - break; - case 5: - kf_bfly5(Fout,fstride,st,m); - break; - default: - kf_bfly_generic(Fout,fstride,st,m,p); - break; - } -} - -/* facbuf is populated by p1,m1,p2,m2, ... - where - p[i] * m[i] = m[i-1] - m0 = n */ -static void kf_factor(int n,int * facbuf) { - int p=4; - double floor_sqrt; - floor_sqrt = floor( sqrt((double)n) ); - - /* factor out powers of 4, powers of 2, then any remaining primes */ - do { - while (n % p) { - switch (p) { - case 4: - p = 2; - break; - case 2: - p = 3; - break; - default: - p += 2; - break; - } - if (p > floor_sqrt) - p = n; /* no more factors, skip to end */ - } - n /= p; - *facbuf++ = p; - *facbuf++ = n; - } while (n > 1); -} - -static void mrkiss_fft_stride(mrkiss_fft_cfg st,const mrkiss_fft_cpx *fin,mrkiss_fft_cpx *fout,int in_stride) { - if (fin == fout) { - /* NOTE: this is not really an in-place FFT algorithm. */ - /* It just performs an out-of-place FFT into a temp buffer */ - mrkiss_fft_cpx * tmpbuf = (mrkiss_fft_cpx*)MRKISS_FFT_TMP_ALLOC( sizeof(mrkiss_fft_cpx)*st->nfft); - kf_work(tmpbuf,fin,1,in_stride, st->factors,st); - memcpy(fout,tmpbuf,sizeof(mrkiss_fft_cpx)*st->nfft); - MRKISS_FFT_TMP_FREE(tmpbuf); - } else { - kf_work( fout, fin, 1,in_stride, st->factors,st ); - } -} - -static void mrkiss_fft(mrkiss_fft_cfg cfg,const mrkiss_fft_cpx *fin,mrkiss_fft_cpx *fout) { - mrkiss_fft_stride(cfg,fin,fout,1); -} - -/* end of include from kiss_fft.c --------------------------------------------------*/ - -static void mrkiss_fft_alloc(int nfft, mrkiss_fft_cfg cfg) { - int i; - cfg->nfft = nfft; - cfg->inverse = 0; - - for (i=0; itwiddles+i, phase); - } - kf_factor(nfft, cfg->factors); -} - -static void mrkiss_fftr(mrkiss_fftr_cfg st, const mrkiss_fft_scalar *timedata, mrkiss_fft_cpx *freqdata) { - /* input buffer timedata is stored row-wise */ - int k,ncfft; - mrkiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; - - ncfft = st->substate->nfft; - - /*perform the parallel fft of two real signals packed in real,imag*/ - mrkiss_fft( st->substate , (const mrkiss_fft_cpx*)timedata, st->tmpbuf ); - - tdc.r = st->tmpbuf[0].r; - tdc.i = st->tmpbuf[0].i; - C_FIXDIV(tdc,2); - CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); - CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); - freqdata[0].r = tdc.r + tdc.i; - freqdata[ncfft].r = tdc.r - tdc.i; - freqdata[ncfft].i = freqdata[0].i = 0; - - for ( k=1; k <= ncfft/2 ; ++k ) { - fpk = st->tmpbuf[k]; - fpnk.r = st->tmpbuf[ncfft-k].r; - fpnk.i = - st->tmpbuf[ncfft-k].i; - C_FIXDIV(fpk,2); - C_FIXDIV(fpnk,2); - - C_ADD( f1k, fpk , fpnk ); - C_SUB( f2k, fpk , fpnk ); - C_MUL( tw , f2k , st->super_twiddles[k-1]); - - freqdata[k].r = HALF_OF(f1k.r + tw.r); - freqdata[k].i = HALF_OF(f1k.i + tw.i); - freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); - freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); - } -} - -int ModelicaFFT_kiss_fftr(_In_ double* u, size_t nu, _In_ double* work, size_t nwork, - _Out_ double *amplitudes, _Out_ double *phases) { - - /* Compute real FFT with mrkiss_fftr - -> u[nu] : Real data at sample points; nu must be even - -> work[nwork] : Work array; nwork >= 3*nu + 2*nf (nf = nu/2+1) - <- amplitude[nf]: Amplitudes; nf = nu/2+1 - <- phases [nf]: phases - <- return : info = 0: computation o.k. - = 1: nu is not even - = 2: nwork is wrong - = 3: another error - - */ - int i; - int nu2 = (int)(nu / 2); - int nf = nu2+1; - - struct mrkiss_fft_state fft_obj; - struct mrkiss_fftr_state fftr_obj; - mrkiss_fft_cpx *freqdata; - - /* Check dimensions */ - if ( nu % 2 != 0 ) return 1; - if ( nwork < 3*nu + 2*(nu/2+1) ) return 2; - - /* Set values of struct fft_obj */ - fft_obj.twiddles = (mrkiss_fft_cpx *) &work[0]; /* length nu (2*nu2) */ - mrkiss_fft_alloc(nu2, &fft_obj); - - /* Set values of struct fftr_obj */ - fftr_obj.substate = &fft_obj; - fftr_obj.tmpbuf = (mrkiss_fft_cpx *) &work[nu]; /* length: nu */ - fftr_obj.super_twiddles = (mrkiss_fft_cpx *) &work[nu+nu]; /* length: nu */ - for (i = 0; i < nu2/2; ++i) { - double phase = - -3.14159265358979323846264338327 * ((double) (i+1) / nu2 + .5); - kf_cexp (fftr_obj.super_twiddles+i,phase); - } - - /* Compute FFT */ - freqdata = (mrkiss_fft_cpx *) &work[nu+nu+nu]; /* length: 2*nf */ - mrkiss_fftr(&fftr_obj, u, freqdata); - for (i=0; i - -#if !defined(MODELICA_EXPORT) -#if defined(__cplusplus) -#define MODELICA_EXPORT extern "C" -#else -#define MODELICA_EXPORT -#endif -#endif - -/* - * Non-null pointers need to be passed to external functions. - * - * The following macros handle nonnull attributes for GNU C and Microsoft SAL. - */ -#undef MODELICA_NONNULLATTR -#if defined(__GNUC__) -#define MODELICA_NONNULLATTR __attribute__((nonnull)) -#else -#define MODELICA_NONNULLATTR -#endif -#if !defined(__ATTR_SAL) -#undef _In_ -#undef _Out_ -#define _In_ -#define _Out_ -#endif - -MODELICA_EXPORT int ModelicaFFT_kiss_fftr(_In_ double* u, size_t nu, _In_ double* work, size_t nwork, - _Out_ double *amplitudes, _Out_ double *phases) MODELICA_NONNULLATTR; - -#endif diff --git a/ModelicaExternalC/C-Sources/ModelicaIO.c b/ModelicaExternalC/C-Sources/ModelicaIO.c deleted file mode 100644 index da1b90688..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaIO.c +++ /dev/null @@ -1,1339 +0,0 @@ -/* ModelicaIO.c - Array I/O functions - - Copyright (C) 2016-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* Definition of interface to external functions for array I/O - in the Modelica Standard Library: - - Modelica.Utilities.Streams.readMatrixSize - Modelica.Utilities.Streams.readRealMatrix - Modelica.Utilities.Streams.writeRealMatrix - - Changelog: - Dec. 22, 2020: by Thomas Beutlich - Added reading of CSV files (ticket #1153) - - July 08, 2020: by Thomas Beutlich - Improved error message if reading text file with zero bytes - (ticket #3603) - - Jan. 15, 2018: by Thomas Beutlich, ESI ITI GmbH - Added support to ignore UTF-8 BOM if reading text file - (ticket #2404) - - Apr. 12, 2017: by Thomas Beutlich, ESI ITI GmbH - Improved error messages if reading struct arrays from - MATLAB MAT-file fails (ticket #2105) - - Mar. 08, 2017: by Thomas Beutlich, ESI ITI GmbH - Added ModelicaIO_readRealTable from ModelicaStandardTables - (ticket #2192) - - Feb. 07, 2017: by Thomas Beutlich, ESI ITI GmbH - Added support for reading integer and single-precision - variable classes of MATLAB MAT-files (ticket #2106) - - Jan. 31, 2017: by Thomas Beutlich, ESI ITI GmbH - Added diagnostic message for (supported) partial read of table - from a text file (ticket #2151) - - Jan. 07, 2017: by Thomas Beutlich, ESI ITI GmbH - Replaced strtok by re-entrant string tokenize function - (ticket #1153) - - Nov. 23, 2016: by Martin Sjoelund, SICS East Swedish ICT AB - Added NO_LOCALE define flag, in case the OS does - not have this (for example when using GCC compiler, - but not libc). Also added autoconf detection for - this flag, NO_PID, NO_TIME, and NO_FILE_SYSTEM - - Nov. 21, 2016: by Thomas Beutlich, ESI ITI GmbH - Fixed error handling if a variable cannot be found in a - MATLAB MAT-file (ticket #2119) - - Mar. 03, 2016: by Thomas Beutlich, ITI GmbH and Martin Otter, DLR - Implemented a first version (ticket #1856) -*/ - -#if defined(__gnu_linux__) && !defined(NO_FILE_SYSTEM) -#define _GNU_SOURCE 1 -#endif - -#include "ModelicaIO.h" -#include -#include "ModelicaUtilities.h" - -#ifdef NO_FILE_SYSTEM -MODELICA_NORETURN static void ModelicaNotExistError(const char* name) MODELICA_NORETURNATTR; -static void ModelicaNotExistError(const char* name) { - /* Print error message if a function is not implemented */ - ModelicaFormatError("C-Function \"%s\" is called " - "but is not implemented for the actual environment " - "(e.g., because there is no file system available on the machine " - "as for dSPACE or xPC systems)\n", name); -} - -void ModelicaIO_readMatrixSizes(_In_z_ const char* fileName, - _In_z_ const char* matrixName, _Out_ int* dim) { - ModelicaNotExistError("ModelicaIO_readMatrixSizes"); } -void ModelicaIO_readRealMatrix(_In_z_ const char* fileName, - _In_z_ const char* matrixName, _Out_ double* matrix, size_t m, size_t n, - int verbose) { - ModelicaNotExistError("ModelicaIO_readRealMatrix"); } -int ModelicaIO_writeRealMatrix(_In_z_ const char* fileName, - _In_z_ const char* matrixName, _In_ double* matrix, size_t m, size_t n, - int append, _In_z_ const char* version) { - ModelicaNotExistError("ModelicaIO_writeRealMatrix"); return 0; } -double* ModelicaIO_readRealTable(_In_z_ const char* fileName, - _In_z_ const char* matrixName, _Out_ size_t* m, _Out_ size_t* n, - int verbose) { - ModelicaNotExistError("ModelicaIO_readRealTable"); return NULL; } -#else - -#include -#if !defined(NO_LOCALE) -#include -#endif -#include "ModelicaMatIO.h" - -/* The standard way to detect POSIX is to check _POSIX_VERSION, - * which is defined in - */ -#if defined(__unix__) || defined(__linux__) || defined(__APPLE_CC__) -#include -#endif -#if !defined(_POSIX_) && defined(_POSIX_VERSION) -#define _POSIX_ 1 -#endif - -/* Use re-entrant string tokenize function if available */ -#if defined(_POSIX_) -#elif defined(_MSC_VER) && _MSC_VER >= 1400 -#define strtok_r(str, delim, saveptr) strtok_s((str), (delim), (saveptr)) -#else -#define strtok_r(str, delim, saveptr) strtok((str), (delim)) -#endif - -#if !defined(LINE_BUFFER_LENGTH) -#define LINE_BUFFER_LENGTH (64) -#endif -#if !defined(MATLAB_NAME_LENGTH_MAX) -#define MATLAB_NAME_LENGTH_MAX (64) -#endif - -typedef struct MatIO { - mat_t* mat; /* Pointer to MAT-file */ - matvar_t* matvar; /* Pointer to MAT-file variable for data */ - matvar_t* matvarRoot; /* Pointer to MAT-file variable for free */ -} MatIO; - -static double* readMatTable(_In_z_ const char* fileName, _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n) MODELICA_NONNULLATTR; - /* Read a table from a MATLAB MAT-file using MatIO functions - - <- RETURN: Pointer to array (row-wise storage) of table values - */ - -static void readMatIO(_In_z_ const char* fileName, _In_z_ const char* matrixName, - _Inout_ MatIO* matio); - /* Read a variable from a MATLAB MAT-file using MatIO functions */ - -static void readRealMatIO(_In_z_ const char* fileName, _In_z_ const char* matrixName, - _Inout_ MatIO* matio); - /* Read a real variable from a MATLAB MAT-file using MatIO functions */ - -static double* readCsvTable(_In_z_ const char* fileName, _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n, _In_z_ const char* delimiter, - int nHeaderLines) MODELICA_NONNULLATTR; - /* Read a table from a CSV file - - <- RETURN: Pointer to array (row-wise storage) of table values - */ - -static double* readTxtTable(_In_z_ const char* fileName, _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n) MODELICA_NONNULLATTR; - /* Read a table from a text file - - <- RETURN: Pointer to array (row-wise storage) of table values - */ - -static int readLine(_In_ char** buf, _In_ int* bufLen, _In_ FILE* fp) MODELICA_NONNULLATTR; - /* Read line (of unknown and arbitrary length) from a text file */ - -static int IsNumber(char* token); - /* Check, whether a token represents a floating-point number */ - -static void transpose(_Inout_ double* table, size_t nRow, size_t nCol) MODELICA_NONNULLATTR; - /* Cycle-based in-place array transposition */ - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wtautological-compare" -#endif - -void ModelicaIO_readMatrixSizes(_In_z_ const char* fileName, - _In_z_ const char* matrixName, - _Out_ int* dim) { - MatIO matio = {NULL, NULL, NULL}; - - dim[0] = 0; - dim[1] = 0; - - readRealMatIO(fileName, matrixName, &matio); - if (NULL != matio.matvar) { - matvar_t* matvar = matio.matvar; - - dim[0] = (int)matvar->dims[0]; - dim[1] = (int)matvar->dims[1]; - } - - Mat_VarFree(matio.matvarRoot); - (void)Mat_Close(matio.mat); -} - -void ModelicaIO_readRealMatrix(_In_z_ const char* fileName, - _In_z_ const char* matrixName, - _Inout_ double* matrix, size_t m, size_t n, - int verbose) { - MatIO matio = {NULL, NULL, NULL}; - int readError = 0; - - if (verbose == 1) { - /* Print info message, that matrix / file is loading */ - ModelicaFormatMessage("... loading \"%s\" from \"%s\"\n", - matrixName, fileName); - } - - readRealMatIO(fileName, matrixName, &matio); - if (NULL != matio.matvar) { - matvar_t* matvar = matio.matvar; - - /* Check if number of rows matches */ - if (m != matvar->dims[0]) { - Mat_VarFree(matio.matvarRoot); - (void)Mat_Close(matio.mat); - ModelicaFormatError( - "Cannot read %lu rows of array \"%s(%lu,%lu)\" " - "from file \"%s\"\n", (unsigned long)m, matrixName, - (unsigned long)matvar->dims[0], (unsigned long)matvar->dims[1], - fileName); - return; - } - - /* Check if number of columns matches */ - if (n != matvar->dims[1]) { - Mat_VarFree(matio.matvarRoot); - (void)Mat_Close(matio.mat); - ModelicaFormatError( - "Cannot read %lu columns of array \"%s(%lu,%lu)\" " - "from file \"%s\"\n", (unsigned long)n, matrixName, - (unsigned long)matvar->dims[0], (unsigned long)matvar->dims[1], - fileName); - return; - } - - { - int start[2] = {0, 0}; - int stride[2] = {1, 1}; - int edge[2]; - edge[0] = (int)matvar->dims[0]; - edge[1] = (int)matvar->dims[1]; - readError = Mat_VarReadData(matio.mat, matvar, matrix, start, stride, edge); - } - } - - Mat_VarFree(matio.matvarRoot); - (void)Mat_Close(matio.mat); - - if (readError == 0 && NULL != matrix) { - /* Array is stored column-wise -> need to transpose */ - transpose(matrix, m, n); - } - else { - ModelicaFormatError( - "Error when reading numeric data of matrix \"%s(%lu,%lu)\" " - "from file \"%s\"\n", matrixName, (unsigned long)m, - (unsigned long)n, fileName); - } -} - -int ModelicaIO_writeRealMatrix(_In_z_ const char* fileName, - _In_z_ const char* matrixName, - _In_ double* matrix, size_t m, size_t n, - int append, - _In_z_ const char* version) { - int status; - mat_t* mat; - matvar_t* matvar; - size_t dims[2]; - double* aT; - enum mat_ft matv; - enum matio_compression matc; - - if ((0 != strcmp(version, "4")) && (0 != strcmp(version, "6")) && (0 != strcmp(version, "7")) && (0 != strcmp(version, "7.3"))) { - ModelicaFormatError("Invalid version %s for file \"%s\"\n", version, fileName); - return 0; - } - if (0 == strcmp(version, "4")) { - matv = MAT_FT_MAT4; - matc = MAT_COMPRESSION_NONE; - } - else if (0 == strcmp(version, "7.3")) { - matv = MAT_FT_MAT73; - matc = MAT_COMPRESSION_ZLIB; - } - else if (0 == strcmp(version, "7")) { - matv = MAT_FT_MAT5; - matc = MAT_COMPRESSION_ZLIB; - } - else { - matv = MAT_FT_MAT5; - matc = MAT_COMPRESSION_NONE; - } - - if (append == 0) { - mat = Mat_CreateVer(fileName, NULL, matv); - if (NULL == mat) { - ModelicaFormatError("Not possible to newly create file \"%s\"\n(maybe version 7.3 not supported)\n", fileName); - return 0; - } - } else { - mat = Mat_Open(fileName, (int)MAT_ACC_RDWR | matv); - if (NULL == mat) { - ModelicaFormatError("Not possible to open file \"%s\"\n", fileName); - return 0; - } - } - - /* MAT file array is stored column-wise -> need to transpose */ - aT = (double*)malloc(m*n*sizeof(double)); - if (NULL == aT) { - (void)Mat_Close(mat); - ModelicaError("Memory allocation error\n"); - return 0; - } - memcpy(aT, matrix, m*n*sizeof(double)); - transpose(aT, n, m); - - if (append != 0) { - (void)Mat_VarDelete(mat, matrixName); - } - - dims[0] = m; - dims[1] = n; - matvar = Mat_VarCreate(matrixName, MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, aT, MAT_F_DONT_COPY_DATA); - status = Mat_VarWrite(mat, matvar, matc); - Mat_VarFree(matvar); - (void)Mat_Close(mat); - free(aT); - if (status != 0) { - ModelicaFormatError("Cannot write variable \"%s\" to \"%s\"\n", matrixName, fileName); - return 0; - } - return 1; -} - -double* ModelicaIO_readRealTable(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n, - int verbose) { - return ModelicaIO_readRealTable2(fileName, tableName, m, n, verbose, ",", 0); -} - -double* ModelicaIO_readRealTable2(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n, - int verbose, _In_z_ const char* delimiter, - int nHeaderLines) { - double* table; - const char* ext; - int isMatExt = 0; - int isCsvExt = 0; - - /* Table file can be either text or binary MATLAB MAT-file */ - ext = strrchr(fileName, '.'); - if (NULL != ext) { - if (0 == strncmp(ext, ".mat", 4) || - 0 == strncmp(ext, ".MAT", 4)) { - isMatExt = 1; - } - else if (0 == strncmp(ext, ".csv", 4) || - 0 == strncmp(ext, ".CSV", 4)) { - isCsvExt = 1; - if (strlen(delimiter) != 1) { - ModelicaFormatError("Invalid column delimiter \"%s\", must be a single character.\n", delimiter); - return NULL; - } - } - } - - if (verbose == 1) { - /* Print info message, that table / file is loading */ - ModelicaFormatMessage("... loading \"%s\" from \"%s\"\n", - tableName, fileName); - } - - if (isMatExt == 1) { - table = readMatTable(fileName, tableName, m, n); - } - else if (isCsvExt == 1) { - table = readCsvTable(fileName, tableName, m, n, delimiter, nHeaderLines); - } - else { - table = readTxtTable(fileName, tableName, m, n); - } - return table; -} - -void ModelicaIO_freeRealTable(double* table) { - free(table); -} - -static double* readMatTable(_In_z_ const char* fileName, _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n) { - double* table = NULL; - MatIO matio = {NULL, NULL, NULL}; - int readError = 0; - - *m = 0; - *n = 0; - - readRealMatIO(fileName, tableName, &matio); - if (NULL != matio.matvar) { - matvar_t* matvar = matio.matvar; - - table = (double*)malloc(matvar->dims[0]*matvar->dims[1]*sizeof(double)); - if (NULL == table) { - Mat_VarFree(matio.matvarRoot); - (void)Mat_Close(matio.mat); - ModelicaError("Memory allocation error\n"); - return NULL; - } - - { - int start[2] = {0, 0}; - int stride[2] = {1, 1}; - int edge[2]; - edge[0] = (int)matvar->dims[0]; - edge[1] = (int)matvar->dims[1]; - readError = Mat_VarReadData(matio.mat, matvar, table, start, stride, edge); - *m = matvar->dims[0]; - *n = matvar->dims[1]; - } - } - - Mat_VarFree(matio.matvarRoot); - (void)Mat_Close(matio.mat); - - if (readError == 0 && NULL != table) { - /* Array is stored column-wise -> need to transpose */ - transpose(table, *m, *n); - } - else { - size_t dim[2]; - - dim[0] = *m; - dim[1] = *n; - *m = 0; - *n = 0; - free(table); - table = NULL; - ModelicaFormatError( - "Error when reading numeric data of matrix \"%s(%lu,%lu)\" " - "from file \"%s\"\n", tableName, (unsigned long)dim[0], - (unsigned long)dim[1], fileName); - } - return table; -} - -static void readMatIO(_In_z_ const char* fileName, - _In_z_ const char* matrixName, _Inout_ MatIO* matio) { - mat_t* mat; - matvar_t* matvar; - matvar_t* matvarRoot; - char* matrixNameCopy; - char* token; -#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400) - char* nextToken = NULL; -#endif - char* prevToken; - int err = 0; - - mat = Mat_Open(fileName, (int)MAT_ACC_RDONLY); - if (NULL == mat) { - ModelicaFormatError("Not possible to open file \"%s\": " - "No such file or directory\n", fileName); - return; - } - - matrixNameCopy = (char*)malloc((strlen(matrixName) + 1) * sizeof(char)); - if (NULL != matrixNameCopy) { - strcpy(matrixNameCopy, matrixName); - } - else { - (void)Mat_Close(mat); - ModelicaError("Memory allocation error\n"); - return; - } - - token = strtok_r(matrixNameCopy, ".", &nextToken); - matvarRoot = Mat_VarReadInfo(mat, NULL == token ? matrixName : token); - if (NULL == matvarRoot) { - (void)Mat_Close(mat); - if (NULL == token) { - free(matrixNameCopy); - ModelicaFormatError( - "Variable \"%s\" not found on file \"%s\".\n", - matrixName, fileName); - } - else { - char matrixNameBuf[MATLAB_NAME_LENGTH_MAX]; - char dots[4]; - if (strlen(token) > MATLAB_NAME_LENGTH_MAX - 1) { - strncpy(matrixNameBuf, token, MATLAB_NAME_LENGTH_MAX - 1); - matrixNameBuf[MATLAB_NAME_LENGTH_MAX - 1] = '\0'; - strcpy(dots, "..."); - } - else { - strcpy(matrixNameBuf, token); - dots[0] = '\0'; - } - free(matrixNameCopy); - ModelicaFormatError( - "Variable \"%s%s\" not found on file \"%s\".\n", - matrixNameBuf, dots, fileName); - } - return; - } - - matvar = matvarRoot; - prevToken = token; - token = strtok_r(NULL, ".", &nextToken); - /* Get field while matvar is of struct class and of 1x1 size */ - while (NULL != token && NULL != matvar) { - if (matvar->class_type == MAT_C_STRUCT && matvar->rank == 2 && - matvar->dims[0] == 1 && matvar->dims[1] == 1) { - matvar = Mat_VarGetStructField(matvar, (void*)token, MAT_BY_NAME, 0); - token = strtok_r(NULL, ".", &nextToken); - } - else if (matvar->class_type != MAT_C_STRUCT) { - err = 1; - matvar = NULL; - break; - } - else if (matvar->rank != 2) { - err = 2; - matvar = NULL; - break; - } - else if (matvar->dims[0] != 1 || matvar->dims[2] != 1) { - err = 3; - matvar = NULL; - break; - } - } - - if (NULL == matvar) { - Mat_VarFree(matvarRoot); - (void)Mat_Close(mat); - if (NULL != token) { - char matrixNameBuf[MATLAB_NAME_LENGTH_MAX]; - char dots[4]; - if (strlen(prevToken) > MATLAB_NAME_LENGTH_MAX - 1) { - strncpy(matrixNameBuf, prevToken, MATLAB_NAME_LENGTH_MAX - 1); - matrixNameBuf[MATLAB_NAME_LENGTH_MAX - 1] = '\0'; - strcpy(dots, "..."); - } - else { - strcpy(matrixNameBuf, prevToken); - dots[0] = '\0'; - } - free(matrixNameCopy); - if (1 == err) { - ModelicaFormatError( - "Variable \"%s%s\" of \"%s\" is not a struct array.\n", - matrixNameBuf, dots, matrixName); - } - else if (2 == err) { - ModelicaFormatError( - "Variable \"%s%s\" of \"%s\" is not a struct array " - "of rank 2.\n", matrixNameBuf, dots, matrixName); - } - else if (3 == err) { - ModelicaFormatError( - "Variable \"%s%s\" of \"%s\" is not a 1x1 struct array.\n", - matrixNameBuf, dots, matrixName); - } - } - else { - free(matrixNameCopy); - ModelicaFormatError( - "Variable \"%s\" not found on file \"%s\".\n", matrixName, fileName); - } - return; - } - free(matrixNameCopy); - - /* Check if matvar is a matrix */ - if (matvar->rank != 2) { - Mat_VarFree(matvarRoot); - (void)Mat_Close(mat); - ModelicaFormatError( - "Variable \"%s\" is not of rank 2.\n", matrixName); - return; - } - - /* Set output fields for MatIO structure */ - matio->mat = mat; - matio->matvar = matvar; - matio->matvarRoot = matvarRoot; -} - -static void readRealMatIO(_In_z_ const char* fileName, - _In_z_ const char* matrixName, _Inout_ MatIO* matio) { - readMatIO(fileName, matrixName, matio); - if (NULL != matio->matvar) { - matvar_t* matvar = matio->matvar; - - /* Check if variable class of matvar is numeric (and thus non-sparse) */ - if (matvar->class_type != MAT_C_DOUBLE && matvar->class_type != MAT_C_SINGLE && - matvar->class_type != MAT_C_INT8 && matvar->class_type != MAT_C_UINT8 && - matvar->class_type != MAT_C_INT16 && matvar->class_type != MAT_C_UINT16 && - matvar->class_type != MAT_C_INT32 && matvar->class_type != MAT_C_UINT32 && - matvar->class_type != MAT_C_INT64 && matvar->class_type != MAT_C_UINT64) { - Mat_VarFree(matio->matvarRoot); - (void)Mat_Close(matio->mat); - ModelicaFormatError("Matrix \"%s\" is not a " - "numeric array.\n", matrixName); - return; - } - matvar->class_type = MAT_C_DOUBLE; - - /* Check if matvar is purely real-valued */ - if (matvar->isComplex) { - Mat_VarFree(matio->matvarRoot); - (void)Mat_Close(matio->mat); - ModelicaFormatError("Matrix \"%s\" must not be complex.\n", - matrixName); - return; - } - } -} - -static int IsNumber(char* token) { - int foundExponentSign = 0; - int foundExponent = 0; - int foundDec = 0; - int foundDigit = 0; - int isNumber = 1; - int k; - - if (token[0] == '-' || token[0] == '+') { - k = 1; - } - else { - k = 0; - } - while (token[k] != '\0') { - if (token[k] >= '0' && token[k] <= '9') { - k++; - foundDigit++; - } - else if (token[k] == '.' && foundDec == 0 && - foundExponent == 0 && foundExponentSign == 0) { - foundDec = 1; - k++; - } - else if ((token[k] == 'e' || token[k] == 'E') && - foundExponent == 0 && foundDigit > 0) { - foundExponent = 1; - foundDigit = 0; - k++; - } - else if ((token[k] == '-' || token[k] == '+') && - foundExponent == 1 && foundExponentSign == 0) { - foundExponentSign = 1; - k++; - } - else { - isNumber = 0; - break; - } - } - return isNumber && foundDigit > 0; -} - -static double* readCsvTable(_In_z_ const char* fileName, _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n, _In_z_ const char* delimiter, - int nHeaderLines) { - double* table = NULL; - char* buf; - int bufLen = LINE_BUFFER_LENGTH; - FILE* fp; - int readError; - unsigned long nRow = 0; - unsigned long nCol = 0; - unsigned long lineNo = 1; -#if defined(NO_LOCALE) - const char * const dec = "."; -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - _locale_t loc; -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - locale_t loc; -#else - char* dec; -#endif - char delimTable[5] = " \t\r"; - if (delimiter[0] != ' ' && delimiter[0] != '\t' && delimiter[0] != '\r') { - strncat(delimTable, delimiter, 1); - } - - fp = fopen(fileName, "r"); - if (NULL == fp) { - ModelicaFormatError("Not possible to open file \"%s\": " - "No such file or directory\n", fileName); - return NULL; - } - - buf = (char*)malloc(LINE_BUFFER_LENGTH*sizeof(char)); - if (NULL == buf) { - fclose(fp); - ModelicaError("Memory allocation error\n"); - return NULL; - } - - /* Ignore file header */ - while (lineNo <= (unsigned long)nHeaderLines) { - if ((readError = readLine(&buf, &bufLen, fp)) != 0) { - free(buf); - fclose(fp); - if (readError < 0) { - ModelicaFormatError( - "Error reading line %lu from file \"%s\": " - "End-Of-File reached.\n", lineNo, fileName); - } - return NULL; - } - lineNo++; - } - -#if defined(NO_LOCALE) -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - loc = _create_locale(LC_NUMERIC, "C"); -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - loc = newlocale(LC_NUMERIC, "C", NULL); -#else - dec = localeconv()->decimal_point; -#endif - - /* First pass: Loop over lines of file and determine dimensions */ - while (readLine(&buf, &bufLen, fp) == 0) { - nRow++; - if (nRow == 1) { -#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400) - char* nextToken = NULL; -#endif - char* token = strtok_r(buf, delimTable, &nextToken); - while (NULL != token) { - token = strtok_r(NULL, delimTable, &nextToken); - nCol++; - } - } - } - - /* Reset for second pass */ - fseek(fp, 0, SEEK_SET); - lineNo = 1; - /* Ignore file header */ - while (lineNo <= (unsigned long)nHeaderLines) { - readLine(&buf, &bufLen, fp); - lineNo++; - } - lineNo--; - - { - size_t i = 0; - - table = (double*)malloc(nRow*nCol*sizeof(double)); - if (NULL == table) { - *m = 0; - *n = 0; - free(buf); - fclose(fp); -#if defined(NO_LOCALE) -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - _free_locale(loc); -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - freelocale(loc); -#endif - ModelicaError("Memory allocation error\n"); - return table; - } - - readError = 0; - /* Loop over rows and store table row-wise */ - for (i = 0; i < nRow; i++) { - size_t j = 0; - char* token; - char* endptr; -#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400) - char* nextToken = NULL; -#endif - if (readError != 0) { - break; - } - - lineNo++; - readError = readLine(&buf, &bufLen, fp) != 0; -#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400) - nextToken = NULL; -#endif - token = strtok_r(buf, delimTable, &nextToken); - for (j = 0; j < nCol; j++) { - if (token == NULL) { - readError = 1; - break; - } -#if !defined(NO_LOCALE) && (defined(_MSC_VER) && _MSC_VER >= 1400) - table[i*nCol + j] = _strtod_l(token, &endptr, loc); - if (*endptr != 0) { - readError = 1; - } -#elif !defined(NO_LOCALE) && (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) - table[i*nCol + j] = strtod_l(token, &endptr, loc); - if (*endptr != 0) { - readError = 1; - } -#else - if (*dec == '.') { - table[i*nCol + j] = strtod(token, &endptr); - } - else if (NULL == strchr(token, '.')) { - table[i*nCol + j] = strtod(token, &endptr); - } - else { - char* token2 = (char*)malloc( - (strlen(token) + 1)*sizeof(char)); - if (NULL != token2) { - char* p; - strcpy(token2, token); - p = strchr(token2, '.'); - *p = *dec; - table[i*nCol + j] = strtod(token2, &endptr); - if (*endptr != 0) { - readError = 1; - } - free(token2); - } - else { - *m = 0; - *n = 0; - free(buf); - fclose(fp); - readError = 1; - ModelicaError("Memory allocation error\n"); - break; - } - } -#endif - if (readError == 0) { - token = strtok_r(NULL, delimTable, &nextToken); - } - else { - break; - } - } - } - } - - free(buf); - fclose(fp); -#if defined(NO_LOCALE) -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - _free_locale(loc); -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - freelocale(loc); -#endif - - if (readError == 0) { - *m = (size_t)nRow; - *n = (size_t)nCol; - } - else { - free(table); - table = NULL; - *m = 0; - *n = 0; - ModelicaFormatError( - "Error in line %lu when reading numeric data of matrix " - "\"%s(%lu,%lu)\" from file \"%s\"\n", lineNo, - tableName, nRow, nCol, fileName); - } - return table; -} - -static double* readTxtTable(_In_z_ const char* fileName, _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n) { -#define DELIM_TABLE_HEADER " \t(,)\r" -#define DELIM_TABLE_NUMBER " \t,;\r" - double* table = NULL; - char* buf; - char* header; - int bufLen = LINE_BUFFER_LENGTH; - FILE* fp; - int foundTable = 0; - int readError; - unsigned long nRow = 0; - unsigned long nCol = 0; - unsigned long lineNo = 1; - const unsigned char txtHeader[2] = { 0x23,0x31 }; - const unsigned char utf8BOM[3] = { 0xef,0xbb,0xbf }; -#if defined(NO_LOCALE) - const char * const dec = "."; -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - _locale_t loc; -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - locale_t loc; -#else - char* dec; -#endif - - fp = fopen(fileName, "r"); - if (NULL == fp) { - ModelicaFormatError("Not possible to open file \"%s\": " - "No such file or directory\n", fileName); - return NULL; - } - - buf = (char*)calloc(LINE_BUFFER_LENGTH, sizeof(char)); - if (NULL == buf) { - fclose(fp); - ModelicaError("Memory allocation error\n"); - return NULL; - } - - /* Read file header */ - if ((readError = readLine(&buf, &bufLen, fp)) == EOF) { - free(buf); - fclose(fp); - if (readError < 0) { - ModelicaFormatError( - "Error reading first line from file \"%s\": " - "End-Of-File reached.\n", fileName); - } - return NULL; - } - - header = buf; - /* Ignore optional UTF-8 BOM */ - if (0 == memcmp(buf, utf8BOM, sizeof(utf8BOM))) - { - header += sizeof(utf8BOM); - } - - /* Expected file header format: "#1" */ - if (0 != memcmp(header, txtHeader, sizeof(txtHeader))) { - size_t len = strlen(header); - fclose(fp); - if (len == 0) { - free(buf); - ModelicaFormatError( - "Error reading format and version information in first " - "line of file \"%s\": \"#1\" expected.\n", fileName); - } - else if (len == 1) { - char c0 = header[0]; - free(buf); - ModelicaFormatError( - "Error reading format and version information in first " - "line of file \"%s\": \"#1\" expected, but \"0x%02x\" found.\n", - fileName, (int)(c0 & 0xff)); - } - else { - char c0 = header[0]; - char c1 = header[1]; - free(buf); - ModelicaFormatError( - "Error reading format and version information in first " - "line of file \"%s\": \"#1\" expected, but \"0x%02x0x%02x\" " - "found.\n", fileName, (int)(c0 & 0xff), (int)(c1 & 0xff)); - } - return NULL; - } - -#if defined(NO_LOCALE) -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - loc = _create_locale(LC_NUMERIC, "C"); -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - loc = newlocale(LC_NUMERIC, "C", NULL); -#else - dec = localeconv()->decimal_point; -#endif - - /* Loop over lines of file */ - while (readLine(&buf, &bufLen, fp) == 0) { - char* token; - char* endptr; -#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400) - char* nextToken = NULL; -#endif - - lineNo++; - /* Expected table header format: "dataType tableName(nRow,nCol)" */ - token = strtok_r(buf, DELIM_TABLE_HEADER, &nextToken); - if (NULL == token) { - continue; - } - if ((0 != strcmp(token, "double")) && (0 != strcmp(token, "float"))) { - continue; - } - token = strtok_r(NULL, DELIM_TABLE_HEADER, &nextToken); - if (NULL == token) { - continue; - } - if (0 == strcmp(token, tableName)) { - foundTable = 1; - } - else { - continue; - } - token = strtok_r(NULL, DELIM_TABLE_HEADER, &nextToken); - if (NULL == token) { - continue; - } -#if !defined(NO_LOCALE) && (defined(_MSC_VER) && _MSC_VER >= 1400) - nRow = (unsigned long)_strtol_l(token, &endptr, 10, loc); -#elif !defined(NO_LOCALE) && (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) - nRow = (unsigned long)strtol_l(token, &endptr, 10, loc); -#else - nRow = (unsigned long)strtol(token, &endptr, 10); -#endif - if (*endptr != 0) { - continue; - } - token = strtok_r(NULL, DELIM_TABLE_HEADER, &nextToken); - if (NULL == token) { - continue; - } -#if !defined(NO_LOCALE) && (defined(_MSC_VER) && _MSC_VER >= 1400) - nCol = (unsigned long)_strtol_l(token, &endptr, 10, loc); -#elif !defined(NO_LOCALE) && (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) - nCol = (unsigned long)strtol_l(token, &endptr, 10, loc); -#else - nCol = (unsigned long)strtol(token, &endptr, 10); -#endif - if (*endptr != 0) { - continue; - } - - { /* foundTable == 1 */ - size_t i = 0; - size_t j = 0; - - table = (double*)malloc(nRow*nCol*sizeof(double)); - if (NULL == table) { - *m = 0; - *n = 0; - free(buf); - fclose(fp); -#if defined(NO_LOCALE) -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - _free_locale(loc); -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - freelocale(loc); -#endif - ModelicaError("Memory allocation error\n"); - return table; - } - - /* Loop over rows and store table row-wise */ - while (readError == 0 && i < nRow) { - int k = 0; - - lineNo++; - if ((readError = readLine(&buf, &bufLen, fp)) != 0) { - break; - } - /* Ignore leading white space */ - while (k < bufLen - 1) { - if (buf[k] != ' ' && buf[k] != '\t') { - break; - } - k++; - } - if (buf[k] == '\0' || buf[k] == '#') { - /* Skip empty or comment line */ - continue; - } -#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400) - nextToken = NULL; -#endif - token = strtok_r(&buf[k], DELIM_TABLE_NUMBER, &nextToken); - while (NULL != token && i < nRow && j < nCol) { - if (token[0] == '#') { - /* Skip trailing comment line */ - break; - } -#if !defined(NO_LOCALE) && (defined(_MSC_VER) && _MSC_VER >= 1400) - table[i*nCol + j] = _strtod_l(token, &endptr, loc); - if (*endptr != 0) { - readError = 1; - } -#elif !defined(NO_LOCALE) && (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) - table[i*nCol + j] = strtod_l(token, &endptr, loc); - if (*endptr != 0) { - readError = 1; - } -#else - if (*dec == '.') { - table[i*nCol + j] = strtod(token, &endptr); - } - else if (NULL == strchr(token, '.')) { - table[i*nCol + j] = strtod(token, &endptr); - } - else { - char* token2 = (char*)malloc( - (strlen(token) + 1)*sizeof(char)); - if (NULL != token2) { - char* p; - strcpy(token2, token); - p = strchr(token2, '.'); - *p = *dec; - table[i*nCol + j] = strtod(token2, &endptr); - if (*endptr != 0) { - readError = 1; - } - free(token2); - } - else { - *m = 0; - *n = 0; - free(buf); - fclose(fp); - readError = 1; - ModelicaError("Memory allocation error\n"); - break; - } - } -#endif - if (++j == nCol) { - i++; /* Increment row index */ - j = 0; /* Reset column index */ - } - if (readError == 0) { - token = strtok_r(NULL, DELIM_TABLE_NUMBER, &nextToken); - continue; - } - else { - break; - } - } - /* Check for trailing non-comment character */ - if (NULL != token && token[0] != '#') { - readError = 1; - /* Check for trailing number (on same line) */ - if (i == nRow && 1 == IsNumber(token)) { - readError = 2; - } - break; - } - /* Extra check for partial table read */ - else if (NULL == token && 0 == readError && i == nRow) { - unsigned long lineNoPartial = lineNo; - int tableReadPartial = 0; - while (readLine(&buf, &bufLen, fp) == 0) { - k = 0; - lineNoPartial++; - /* Ignore leading white space */ - while (k < bufLen - 1) { - if (buf[k] != ' ' && buf[k] != '\t') { - break; - } - k++; - } - if (buf[k] == '\0' || buf[k] == '#') { - /* Skip empty or comment line */ - continue; - } -#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400) - nextToken = NULL; -#endif - token = strtok_r(&buf[k], DELIM_TABLE_NUMBER, &nextToken); - if (NULL != token) { - if (1 == IsNumber(token)) { - tableReadPartial = 1; - } - /* Else, it is not a number: No further check - is performed, if legal or not - */ - } - break; - } - if (1 == tableReadPartial) { - ModelicaFormatWarning( - "The table dimensions of matrix \"%s(%lu,%lu)\" from file " - "\"%s\" do not match the actual table size (line %lu).\n", - tableName, nRow, nCol, fileName, lineNoPartial); - } - break; - } - } - break; - } - } - - free(buf); - fclose(fp); -#if defined(NO_LOCALE) -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - _free_locale(loc); -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - freelocale(loc); -#endif - if (foundTable == 0) { - ModelicaFormatError( - "Table matrix \"%s\" not found on file \"%s\".\n", - tableName, fileName); - return table; - } - - if (readError == 0) { - *m = (size_t)nRow; - *n = (size_t)nCol; - } - else { - free(table); - table = NULL; - *m = 0; - *n = 0; - if (readError == EOF) { - ModelicaFormatError( - "End-of-file reached when reading numeric data of matrix " - "\"%s(%lu,%lu)\" from file \"%s\"\n", tableName, nRow, - nCol, fileName); - } - else if (readError == 2) { - ModelicaFormatError( - "The table dimensions of matrix \"%s(%lu,%lu)\" from file " - "\"%s\" do not match the actual table size (line %lu).\n", - tableName, nRow, nCol, fileName, lineNo); - } - else { - ModelicaFormatError( - "Error in line %lu when reading numeric data of matrix " - "\"%s(%lu,%lu)\" from file \"%s\"\n", lineNo, tableName, - nRow, nCol, fileName); - } - } - return table; -#undef DELIM_TABLE_HEADER -#undef DELIM_TABLE_NUMBER -} - -static int readLine(_In_ char** buf, _In_ int* bufLen, _In_ FILE* fp) { - char* offset; - int oldBufLen; - - if (fgets(*buf, *bufLen, fp) == NULL) { - return EOF; - } - if (feof(fp)) { - return 0; - } - - do { - char* p; - char* tmp; - - if ((p = strchr(*buf, '\n')) != NULL) { - *p = '\0'; - return 0; - } - if ((p = memchr(*buf, 0, (size_t)(*bufLen - 1))) != NULL) { - return 1; - } - - oldBufLen = *bufLen; - *bufLen *= 2; - tmp = (char*)realloc(*buf, (size_t)*bufLen); - if (NULL == tmp) { - fclose(fp); - free(*buf); - ModelicaError("Memory allocation error\n"); - return 1; - } - *buf = tmp; - offset = &((*buf)[oldBufLen - 1]); - - } while (fgets(offset, oldBufLen + 1, fp)); - - return 0; -} - -static void transpose(_Inout_ double* table, size_t nRow, size_t nCol) { - /* Reference: - - Cycle-based in-place array transposition - (http://en.wikipedia.org/wiki/In-place_matrix_transposition#Non-square_matrices:_Following_the_cycles) - */ - - size_t i; - for (i = 1; i < nRow*nCol - 1; i++) { - size_t x = nRow*(i % nCol) + i/nCol; /* predecessor of i in the cycle */ - /* Continue if cycle is of length one or predecessor already was visited */ - if (x <= i) { - continue; - } - /* Continue if cycle already was visited */ - while (x > i) { - x = nRow*(x % nCol) + x/nCol; - } - if (x < i) { - continue; - } - { - double tmp = table[i]; - size_t s = i; /* start index in the cycle */ - x = nRow*(i % nCol) + i/nCol; /* predecessor of i in the cycle */ - while (x != i) { - table[s] = table[x]; - s = x; - x = nRow*(x % nCol) + x/nCol; - } - table[s] = tmp; - } - } -} - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -#endif diff --git a/ModelicaExternalC/C-Sources/ModelicaIO.h b/ModelicaExternalC/C-Sources/ModelicaIO.h deleted file mode 100644 index c8644aa89..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaIO.h +++ /dev/null @@ -1,176 +0,0 @@ -/* ModelicaIO.h - Array I/O functions header - - Copyright (C) 2016-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* The following #define's are available. - - NO_FILE_SYSTEM : A file system is not present (e.g. on dSPACE or xPC). - NO_LOCALE : locale.h is not present (e.g. on AVR). - MODELICA_EXPORT: Prefix used for function calls. If not defined, blank is used - Useful definition: - - "__declspec(dllexport)" if included in a DLL and the - functions shall be visible outside of the DLL - - Changelog: - Dec. 22, 2020: by Thomas Beutlich - Added reading of CSV files (ticket #1153) - - Mar. 08, 2017: by Thomas Beutlich, ESI ITI GmbH - Added ModelicaIO_readRealTable from ModelicaStandardTables - (ticket #2192) - - Mar. 03, 2016: by Thomas Beutlich, ITI GmbH and Martin Otter, DLR - Implemented a first version (ticket #1856) -*/ - -#ifndef MODELICA_IO_H_ -#define MODELICA_IO_H_ - -#include - -#if !defined(MODELICA_EXPORT) -#if defined(__cplusplus) -#define MODELICA_EXPORT extern "C" -#else -#define MODELICA_EXPORT -#endif -#endif - -/* - * Non-null pointers and esp. null-terminated strings need to be passed to - * external functions. - * - * The following macros handle nonnull attributes for GNU C and Microsoft SAL. - */ -#undef MODELICA_NONNULLATTR -#if defined(__GNUC__) -#define MODELICA_NONNULLATTR __attribute__((nonnull)) -#else -#define MODELICA_NONNULLATTR -#endif -#if !defined(__ATTR_SAL) -#undef _In_ -#undef _In_z_ -#undef _Inout_ -#undef _Out_ -#define _In_ -#define _In_z_ -#define _Inout_ -#define _Out_ -#endif - -MODELICA_EXPORT void ModelicaIO_readMatrixSizes(_In_z_ const char* fileName, - _In_z_ const char* matrixName, - _Out_ int* dim) MODELICA_NONNULLATTR; - /* Read matrix dimensions from file - - -> fileName: Name of file - -> matrixName: Name of matrix - -> dim: Output array for number of rows and columns - */ - -MODELICA_EXPORT void ModelicaIO_readRealMatrix(_In_z_ const char* fileName, - _In_z_ const char* matrixName, - _Inout_ double* matrix, size_t m, size_t n, - int verbose) MODELICA_NONNULLATTR; - /* Read matrix from file - - -> fileName: Name of file - -> matrixName: Name of matrix - -> matrix: Output array of dimensions m by n - -> m: Number of rows - -> n: Number of columns - -> verbose: Print message that file is loading - */ - -MODELICA_EXPORT int ModelicaIO_writeRealMatrix(_In_z_ const char* fileName, - _In_z_ const char* matrixName, - _In_ double* matrix, size_t m, size_t n, - int append, - _In_z_ const char* version) MODELICA_NONNULLATTR; - /* Write matrix to file - - -> fileName: Name of file - -> matrixName: Name of matrix - -> matrix: Input array of dimensions m by n - -> m: Number of rows - -> n: Number of columns - -> append: File append flag - = 1: if matrix is to be appended to (existing) file, - = 0: if file is to be newly created - -> version: Desired file version - = "4": MATLAB MAT-file of version 4 - = "6": MATLAB MAT-file of version 6 - = "7": MATLAB MAT-file of version 7 - = "7.3": MATLAB MAT-file of version 7.3 - */ - -MODELICA_EXPORT double* ModelicaIO_readRealTable(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n, - int verbose) MODELICA_NONNULLATTR; - /* Read matrix and its dimensions from file - Note: Only called from ModelicaStandardTables, but impossible to be called - from a Modelica environment - - -> fileName: Name of file - -> matrixName: Name of matrix - -> m: Number of rows - -> n: Number of columns - -> verbose: Print message that file is loading - <- RETURN: Array of dimensions m by n - */ - -MODELICA_EXPORT double* ModelicaIO_readRealTable2(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _Out_ size_t* m, _Out_ size_t* n, - int verbose, _In_z_ const char* delimiter, - int nHeaderLines) MODELICA_NONNULLATTR; - /* Read matrix and its dimensions from file - Note: Only called from ModelicaStandardTables, but impossible to be called - from a Modelica environment - - -> fileName: Name of file - -> matrixName: Name of matrix - -> m: Number of rows - -> n: Number of columns - -> verbose: Print message that file is loading - -> delimiter: Column delimiter character (CSV file only) - -> nHeaderLines: Number of header lines to ignore (CSV file only) - <- RETURN: Array of dimensions m by n - */ - -MODELICA_EXPORT void ModelicaIO_freeRealTable(double* table); - /* Free table - Note: Only called from ModelicaStandardTables to free the allocated memory by - ModelicaIO_readRealTable - */ - -#endif diff --git a/ModelicaExternalC/C-Sources/ModelicaInternal.c b/ModelicaExternalC/C-Sources/ModelicaInternal.c deleted file mode 100644 index 2dbec6a4d..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaInternal.c +++ /dev/null @@ -1,1383 +0,0 @@ -/* ModelicaInternal.c - External functions for Modelica.Utilities - - Copyright (C) 2002-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* Changelog: - Nov. 17, 2020: by Thomas Beutlich - Fixed reading files with Unix-style line endings on Windows - for ModelicaInternal_readLine/_readFile (ticket #3631) - - Nov. 11, 2020: by Thomas Beutlich - Added getcwd fallback in ModelicaInternal_fullPathName if - realpath fails for non-existing path (ticket #3660) - - Nov. 13, 2019: by Thomas Beutlich - Utilized blockwise I/O in ModelicaInternal_copyFile - (ticket #3229) - - Oct. 10, 2019: by Thomas Beutlich - Fixed month and year correction in ModelicaInternal_getTime - (ticket #3143) - - Jun. 24, 2019: by Thomas Beutlich - Fixed uninitialized memory and realpath behaviour in - ModelicaInternal_fullPathName (ticket #3003) - - Jun. 28, 2018: by Hans Olsson, Dassault Systemes - Proper error message when out of string memory - in ModelicaInternal_readLine (ticket #2676) - - Oct. 23, 2017: by Thomas Beutlich, ESI ITI GmbH - Utilized non-fatal hash insertion, called by HASH_ADD_KEYPTR in - function CacheFileForReading (ticket #2097) - - Apr. 09, 2017: by Thomas Beutlich, ESI ITI GmbH - Fixed macOS support of ModelicaInternal_setenv - (ticket #2235) - - Mar. 27, 2017: by Thomas Beutlich, ESI ITI GmbH - Replaced localtime by re-entrant function - - Jan. 31, 2017: by Thomas Beutlich, ESI ITI GmbH - Fixed WIN32 support of a directory name with a trailing - forward/backward slash character in ModelicaInternal_stat - (ticket #1976) - - Mar. 02, 2016: by Thomas Beutlich, ITI GmbH - Fixed repeated opening of cached file in case of line miss in - ModelicaStreams_openFileForReading (ticket #1939) - - Dec. 10, 2015: by Martin Otter, DLR - Added flags NO_PID and NO_TIME (ticket #1805) - - Oct. 27, 2015: by Thomas Beutlich, ITI GmbH - Added nonnull attributes/annotations (ticket #1436) - - Oct. 05, 2015: by Thomas Beutlich, ITI GmbH - Added functions ModelicaInternal_getpid/_getTime from - ModelicaRandom.c of https://github.com/DLR-SR/Noise - (ticket #1662) - - Nov. 20, 2014: by Thomas Beutlich, ITI GmbH - Fixed platform dependency of ModelicaInternal_readLine/_readFile - (ticket #1580) - - Aug. 22, 2014: by Thomas Beutlich, ITI GmbH - Fixed multi-threaded access of common/shared file cache - (ticket #1556) - - Aug. 11, 2014: by Thomas Beutlich, ITI GmbH - Increased cache size of opened files and made it - thread-safe (ticket #1433) - Made getenv/putenv thread-safe for Visual Studio 2005 and - later (ticket #1433) - - May 21, 2013: by Martin Otter, DLR - Included the improvements from DS Lund (ticket #1104): - - Changed implementation of print to do nothing in case of - missing file-system. Otherwise we just end up with an - error message that is not written, and the failure in - itself is not sufficiently fatal to just stop. - - Caching when reading from file - - Mar, 26, 2013: by Martin Otter, DLR - Changed type of variable valueStart from int to size_t - (ticket #1032) - - Jan. 05, 2013: by Martin Otter, DLR - Removed "static" declarations from the Modelica interface - functions - - Sep. 26, 2004: by Martin Otter, DLR - Added missing implementations, merged code from previous - ModelicaFiles and clean-up of code - - Sep. 09, 2004: by Dag Brueck, Dynasim AB - Further implementation and clean-up of code - - Aug. 24, 2004: by Martin Otter, DLR - Adapted to Dymola 5.3 with minor improvements - - Jan. 07, 2002: by Martin Otter, DLR - First version implemented: - Only tested for _WIN32, but implemented all - functions also for _POSIX_, with the exception of - ModelicaInternal_getFullPath -*/ - -#if defined(__gnu_linux__) && !defined(NO_FILE_SYSTEM) -#define _GNU_SOURCE 1 -#endif - -#include "ModelicaInternal.h" -#include "ModelicaUtilities.h" - -MODELICA_NORETURN static void ModelicaNotExistError(const char* name) MODELICA_NORETURNATTR; -static void ModelicaNotExistError(const char* name) { - /* Print error message if a function is not implemented */ - ModelicaFormatError("C-Function \"%s\" is called\n" - "but is not implemented for the actual environment\n" - "(e.g., because there is no file system available on the machine\n" - "as for dSPACE or xPC systems)", name); -} - -#ifdef NO_FILE_SYSTEM -void ModelicaInternal_mkdir(_In_z_ const char* directoryName) { - ModelicaNotExistError("ModelicaInternal_mkdir"); } -void ModelicaInternal_rmdir(_In_z_ const char* directoryName) { - ModelicaNotExistError("ModelicaInternal_rmdir"); } -int ModelicaInternal_stat(_In_z_ const char* name) { - ModelicaNotExistError("ModelicaInternal_stat"); return 0; } -void ModelicaInternal_rename(_In_z_ const char* oldName, - _In_z_ const char* newName) { - ModelicaNotExistError("ModelicaInternal_rename"); } -void ModelicaInternal_removeFile(_In_z_ const char* file) { - ModelicaNotExistError("ModelicaInternal_removeFile"); } -void ModelicaInternal_copyFile(_In_z_ const char* oldFile, - _In_z_ const char* newFile) { - ModelicaNotExistError("ModelicaInternal_copyFile"); } -void ModelicaInternal_readDirectory(_In_z_ const char* directory, - int nFiles, _Out_ const char** files) { - ModelicaNotExistError("ModelicaInternal_readDirectory"); } -int ModelicaInternal_getNumberOfFiles(_In_z_ const char* directory) { - ModelicaNotExistError("ModelicaInternal_getNumberOfFiles"); return 0; } -const char* ModelicaInternal_fullPathName(_In_z_ const char* name) { - ModelicaNotExistError("ModelicaInternal_fullPathName"); return NULL; } -const char* ModelicaInternal_temporaryFileName(void) { - ModelicaNotExistError("ModelicaInternal_temporaryFileName"); return NULL; } -void ModelicaStreams_closeFile(_In_z_ const char* fileName) { - ModelicaNotExistError("ModelicaStreams_closeFile"); } -void ModelicaInternal_print(_In_z_ const char* string, - _In_z_ const char* fileName) { - if ( fileName[0] == '\0' ) { - /* Write string to terminal */ - ModelicaFormatMessage("%s\n", string); - } - return; } -int ModelicaInternal_countLines(_In_z_ const char* fileName) { - ModelicaNotExistError("ModelicaInternal_countLines"); return 0; } -void ModelicaInternal_readFile(_In_z_ const char* fileName, - _Out_ const char** string, size_t nLines) { - ModelicaNotExistError("ModelicaInternal_readFile"); } -const char* ModelicaInternal_readLine(_In_z_ const char* fileName, - int lineNumber, _Out_ int* endOfFile) { - ModelicaNotExistError("ModelicaInternal_readLine"); return NULL; } -void ModelicaInternal_chdir(_In_z_ const char* directoryName) { - ModelicaNotExistError("ModelicaInternal_chdir"); } -const char* ModelicaInternal_getcwd(int dummy) { - ModelicaNotExistError("ModelicaInternal_getcwd"); return NULL; } -void ModelicaInternal_getenv(_In_z_ const char* name, int convertToSlash, - _Out_ const char** content, _Out_ int* exist) { - ModelicaNotExistError("ModelicaInternal_getenv"); } -void ModelicaInternal_setenv(_In_z_ const char* name, - _In_z_ const char* value, int convertFromSlash) { - ModelicaNotExistError("ModelicaInternal_setenv"); } -#else - -/* The standard way to detect POSIX is to check _POSIX_VERSION, - * which is defined in - */ -#if defined(__unix__) || defined(__linux__) || defined(__APPLE_CC__) - #include -#endif -#if !defined(_POSIX_) && defined(_POSIX_VERSION) - #define _POSIX_ 1 -#endif - -#include "stdint_wrap.h" -#define HASH_NO_STDINT 1 -#define HASH_NONFATAL_OOM 1 -#include "uthash.h" -#include "gconstructor.h" - -#include -#include -#include -#include - -#if defined(__WATCOMC__) - #include - #include - #include -#elif defined(__BORLANDC__) - #include - #include - #include - #include -#elif defined(_WIN32) - #include - #include - #include - - #if defined(__MINGW32__) || defined(__CYGWIN__) /* MinGW and Cygwin have dirent.h */ - #include - #else /* include the opendir/readdir/closedir interface for _WIN32 */ - #include "win32_dirent.h" - #endif - -#elif defined(_POSIX_) || defined(__GNUC__) - #include - #include - #include - #include -#endif - -#if PATH_MAX > 1024 -#define BUFFER_LENGTH PATH_MAX -#else -#define BUFFER_LENGTH 1024 -#endif - -typedef enum { - FileType_NoFile = 1, - FileType_RegularFile, - FileType_Directory, - FileType_SpecialFile /* pipe, FIFO, device, etc. */ -} ModelicaFileType; - -/* Convert to Unix directory separators: */ -#if defined(_WIN32) -static void ModelicaConvertToUnixDirectorySeparator(char* string) { - /* Convert to Unix directory separators */ - char* c = string; - while ( *c ) { - if ( *c == '\\' ) { - *c = '/'; - } - c++; - } -} - -static void ModelicaConvertFromUnixDirectorySeparator(char* string) { - /* Convert from Unix directory separators */ - char* c = string; - while ( *c ) { - if ( *c == '/' ) { - *c = '\\'; - } - c++; - } -} -#else - #define ModelicaConvertToUnixDirectorySeparator(string) ; - #define ModelicaConvertFromUnixDirectorySeparator(string) ; -#endif - -static int readLine(_In_ char** buf, _In_ int* bufLen, _In_ FILE* fp) MODELICA_NONNULLATTR; - /* Read line (of unknown and arbitrary length) from a text file */ - -/* --------------------- Modelica_Utilities.Internal --------------------------------- */ - -void ModelicaInternal_mkdir(_In_z_ const char* directoryName) { - /* Create directory */ -#if defined(__WATCOMC__) || defined(__LCC__) - int result = mkdir(directoryName); -#elif defined(__BORLANDC__) || defined(_WIN32) - int result = _mkdir(directoryName); -#elif defined(_POSIX_) || defined(__GNUC__) - int result = mkdir(directoryName, S_IRUSR | S_IWUSR | S_IXUSR); -#else - ModelicaNotExistError("ModelicaInternal_mkdir"); -#endif -#if defined(__WATCOMC__) || defined(__LCC__) || defined(__BORLANDC__) || defined(_WIN32) || defined(_POSIX_) || defined(__GNUC__) - if (result != 0) { - ModelicaFormatError("Not possible to create new directory\n" - "\"%s\":\n%s", directoryName, strerror(errno)); - } -#endif -} - -void ModelicaInternal_rmdir(_In_z_ const char* directoryName) { - /* Remove directory */ -#if defined(__WATCOMC__) || defined(__LCC__) || defined(_POSIX_) || defined(__GNUC__) - int result = rmdir(directoryName); -#elif defined(__BORLANDC__) || defined(_WIN32) - int result = _rmdir(directoryName); -#else - ModelicaNotExistError("ModelicaInternal_rmdir"); -#endif -#if defined(__WATCOMC__) || defined(__LCC__) || defined(__BORLANDC__) || defined(_WIN32) || defined(_POSIX_) || defined(__GNUC__) - if (result != 0) { - ModelicaFormatError("Not possible to remove directory\n" - "\"%s\":\n%s", directoryName, strerror(errno)); - } -#endif -} - -static ModelicaFileType Internal_stat(_In_z_ const char* name) { - /* Inquire type of file */ - ModelicaFileType type; -#if defined(_WIN32) - struct _stat fileInfo; - int statReturn = _stat(name, &fileInfo); - if (0 != statReturn) { - /* For some reason _stat requires "a:\" and "a:\test1" but fails - * on "a:" and "a:\test1\", respectively. It could be handled in the - * Modelica code, but seems better to have it here. - */ - const char* firstSlash = strpbrk(name, "/\\"); - const char* firstColon = strchr(name, ':'); - const char c = (NULL != firstColon) ? firstColon[1] : '\0'; - size_t len = strlen(name); - if (NULL == firstSlash && NULL != firstColon && '\0' == c) { - char* nameTmp = (char*)malloc((len + 2)*(sizeof(char))); - if (NULL != nameTmp) { - strcpy(nameTmp, name); - strcat(nameTmp, "\\"); - statReturn = _stat(nameTmp, &fileInfo); - free(nameTmp); - } - } - else if (NULL != firstSlash && len > 1 && - ('/' == name[len - 1] || '\\' == name[len - 1])) { - char* nameTmp = (char*)malloc(len*(sizeof(char))); - if (NULL != nameTmp) { - strncpy(nameTmp, name, len - 1); - nameTmp[len - 1] = '\0'; - statReturn = _stat(nameTmp, &fileInfo); - free(nameTmp); - } - } - } - if ( statReturn != 0 ) { - type = FileType_NoFile; - } - else if ( fileInfo.st_mode & S_IFREG ) { - type = FileType_RegularFile; - } - else if ( fileInfo.st_mode & S_IFDIR ) { - type = FileType_Directory; - } - else { - type = FileType_SpecialFile; - } -#elif defined(_POSIX_) || defined(__GNUC__) - struct stat fileInfo; - int statReturn; - statReturn = stat(name, &fileInfo); - if ( statReturn != 0 ) { - type = FileType_NoFile; - } - else if ( S_ISREG(fileInfo.st_mode) ) { - type = FileType_RegularFile; - } - else if ( S_ISDIR(fileInfo.st_mode) ) { - type = FileType_Directory; - } - else { - type = FileType_SpecialFile; - } -#else - type = FileType_NoFile; -#endif - return type; -} - -int ModelicaInternal_stat(_In_z_ const char* name) { -#if defined(_WIN32) || defined(_POSIX_) || defined(__GNUC__) - ModelicaFileType type = Internal_stat(name); -#else - ModelicaFileType type = FileType_NoFile; - ModelicaNotExistError("ModelicaInternal_stat"); -#endif - return type; -} - -void ModelicaInternal_rename(_In_z_ const char* oldName, - _In_z_ const char* newName) { - /* Change the name of a file or of a directory */ - if ( rename(oldName, newName) != 0 ) { - ModelicaFormatError("renaming \"%s\" to \"%s\" failed:\n%s", - oldName, newName, strerror(errno)); - } -} - -void ModelicaInternal_removeFile(_In_z_ const char* file) { - /* Remove file */ - if ( remove(file) != 0 ) { - ModelicaFormatError("Not possible to remove file \"%s\":\n%s", - file, strerror(errno)); - } -} - -void ModelicaInternal_copyFile(_In_z_ const char* oldFile, - _In_z_ const char* newFile) { - /* Copy file */ - const char* modeOld = "rb"; - const char* modeNew = "wb"; - FILE* fpOld; - FILE* fpNew; - ModelicaFileType type; - - /* Check file existence */ - type = Internal_stat(oldFile); - if ( type == FileType_NoFile ) { - ModelicaFormatError("\"%s\" cannot be copied\nbecause it does not exist", oldFile); - return; - } - else if ( type == FileType_Directory ) { - ModelicaFormatError("\"%s\" cannot be copied\nbecause it is a directory", oldFile); - return; - } - else if ( type == FileType_SpecialFile ) { - ModelicaFormatError("\"%s\" cannot be copied\n" - "because it is not a regular file", oldFile); - return; - } - type = Internal_stat(newFile); - if ( type != FileType_NoFile ) { - ModelicaFormatError("\"%s\" cannot be copied\nbecause the target " - "\"%s\" exists", oldFile, newFile); - return; - } - - /* Copy file */ - fpOld = fopen(oldFile, modeOld); - if ( fpOld == NULL ) { - ModelicaFormatError("\"%s\" cannot be copied:\n%s", oldFile, strerror(errno)); - return; - } - fpNew = fopen(newFile, modeNew); - if ( fpNew == NULL ) { - fclose(fpOld); - ModelicaFormatError("\"%s\" cannot be copied to \"%s\":\n%s", - oldFile, newFile, strerror(errno)); - return; - } - { - size_t len; - char buf[BUFSIZ] = {'\0'}; - - while ( (len = fread(buf, sizeof(char), BUFSIZ, fpOld)) > 0 ) { - if ( len != fwrite(buf, sizeof(char), len, fpNew) ) { - fclose(fpOld); - fclose(fpNew); - ModelicaFormatError("Error writing to file \"%s\".", newFile); - return; - } - } - } - fclose(fpOld); - fclose(fpNew); -} - -void ModelicaInternal_readDirectory(_In_z_ const char* directory, int nFiles, - _Out_ const char** files) { - /* Get all file and directory names in a directory in any order - (must be very careful, to call closedir if an error occurs) - */ -#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_WIN32) || defined(_POSIX_) || defined(__GNUC__) - int errnoTemp; - int iFiles = 0; - char *pName; - struct dirent *pinfo; - DIR* pdir; - - /* Open directory information inquiry */ - pdir = opendir(directory); - if ( pdir == NULL ) { - ModelicaFormatError("1: Not possible to get file names of \"%s\":\n%s", - directory, strerror(errno)); - } - - /* Read file and directory names and store them in vector "files" */ - errno = 0; - while ( (pinfo = readdir(pdir)) != NULL ) { - if ( (strcmp(pinfo->d_name, "." ) != 0) && - (strcmp(pinfo->d_name, "..") != 0) ) { - /* Check if enough space in "files" vector */ - if ( iFiles >= nFiles ) { - closedir(pdir); - ModelicaFormatError("Not possible to get file names of \"%s\":\n" - "More files in this directory as reported by nFiles (= %i)", - directory, nFiles); - } - - /* Allocate Modelica memory for file/directory name and copy name */ - pName = ModelicaAllocateStringWithErrorReturn(strlen(pinfo->d_name)); - if ( pName == NULL ) { - errnoTemp = errno; - closedir(pdir); - if ( errnoTemp == 0 ) { - ModelicaFormatError("Not possible to get file names of \"%s\":\n" - "Not enough storage", directory); - } - else { - ModelicaFormatError("Not possible to get file names of \"%s\":\n%s", - directory, strerror(errnoTemp)); - } - } - strcpy(pName, pinfo->d_name); - - /* Save pointer to file */ - files[iFiles] = pName; - iFiles++; - } - } - - if ( errno != 0 ) { - errnoTemp = errno; - closedir(pdir); - ModelicaFormatError("Not possible to get file names of \"%s\":\n%s", - directory, strerror(errnoTemp)); - } - - /* Check, whether the whole "files" vector is filled and close inquiry */ - if ( iFiles != nFiles) { - closedir(pdir); - ModelicaFormatError("Not possible to get file names of \"%s\":\n" - "Less files (= %d) found as defined by argument nNames (= %d)", - directory, iFiles, nFiles); - } - else if ( closedir(pdir) != 0 ) { - ModelicaFormatError("Not possible to get file names of \"%s\":\n%s", - directory, strerror(errno)); - } - -#else - ModelicaNotExistError("ModelicaInternal_readDirectory"); -#endif -} - -int ModelicaInternal_getNumberOfFiles(_In_z_ const char* directory) { - /* Get number of files and directories in a directory */ -#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_WIN32) || defined(_POSIX_) || defined(__GNUC__) - int nFiles = 0; - int errnoTemp; - struct dirent *pinfo; - DIR* pdir; - - pdir = opendir(directory); - if ( pdir == NULL ) { - goto Modelica_ERROR; - } - errno = 0; - while ( (pinfo = readdir(pdir)) != NULL ) { - if ( (strcmp(pinfo->d_name, "." ) != 0) && - (strcmp(pinfo->d_name, "..") != 0) ) { - nFiles++; - } - } - errnoTemp = errno; - closedir(pdir); - if ( errnoTemp != 0 ) { - errno = errnoTemp; - goto Modelica_ERROR; - } - - return nFiles; - -Modelica_ERROR: - ModelicaFormatError("Not possible to get number of files in \"%s\":\n%s", - directory, strerror(errno)); - return 0; -#else - ModelicaNotExistError("ModelicaInternal_getNumberOfFiles"); - return 0; -#endif -} - -/* --------------------- Modelica_Utilities.Files ------------------------------------- */ - -_Ret_z_ const char* ModelicaInternal_fullPathName(_In_z_ const char* name) { - /* Get full path name of file or directory */ - -#if defined(_WIN32) - char* fullName; - char localbuf[BUFFER_LENGTH]; - char* tempName = _fullpath(localbuf, name, sizeof(localbuf)); - if (tempName == NULL) { - ModelicaFormatError("Not possible to construct full path name of \"%s\"\n%s", - name, strerror(errno)); - return ""; - } - fullName = ModelicaAllocateString(strlen(tempName)); - strcpy(fullName, tempName); - ModelicaConvertToUnixDirectorySeparator(fullName); - return fullName; -#elif (_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || _POSIX_VERSION >= 200112L) - char* fullName; - char localbuf[BUFFER_LENGTH]; - size_t len; - /* realpath availability: 4.4BSD, POSIX.1-2001. Using the behaviour of NULL: POSIX.1-2008 */ - char* tempName = realpath(name, localbuf); - if (tempName == NULL) { - goto FALLBACK_getcwd; - } - fullName = ModelicaAllocateString(strlen(tempName) + 1); - strcpy(fullName, tempName); - ModelicaConvertToUnixDirectorySeparator(fullName); - /* Retain trailing slash to match _fullpath behaviour */ - len = strlen(name); - if (len > 0 && '/' == name[len - 1]) { - strcat(fullName, "/"); - } - return fullName; -#elif defined(_POSIX_) - char* fullName; - char localbuf[BUFFER_LENGTH]; -#else - char* fullName = ""; - ModelicaNotExistError("ModelicaInternal_fullPathName"); - return fullName; -#endif - -#if (_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || _POSIX_VERSION >= 200112L) -FALLBACK_getcwd: -#endif -#if (_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED || _POSIX_VERSION >= 200112L || _POSIX_) - { - /* No such system call in _POSIX_ available (except realpath for existing paths) */ - char* cwd = getcwd(localbuf, sizeof(localbuf)); - if (cwd == NULL) { - ModelicaFormatError("Not possible to get current working directory:\n%s", - strerror(errno)); - } - fullName = ModelicaAllocateString(strlen(cwd) + strlen(name) + 1); - if (name[0] != '/') { - /* Any name beginning with "/" is regarded as already being a full path. */ - strcpy(fullName, cwd); - strcat(fullName, "/"); - } - else { - fullName[0] = '\0'; - } - strcat(fullName, name); - } - return fullName; -#endif -} - -_Ret_z_ const char* ModelicaInternal_temporaryFileName(void) { - /* Get full path name of a temporary file name which does not exist */ - char* fullName; - - char* tempName = tmpnam(NULL); - if (tempName == NULL) { - ModelicaFormatError("Not possible to get temporary filename\n%s", strerror(errno)); - return ""; - } - fullName = ModelicaAllocateString(strlen(tempName)); - strcpy(fullName, tempName); - ModelicaConvertToUnixDirectorySeparator(fullName); - - return fullName; -} - -/* --------------------- Abstract data type for stream handles --------------------- */ - -/* Improved for caching of the open files */ -typedef struct FileCache { - char* fileName; /* Key = File name */ - FILE* fp /* File pointer */; - char* buf; - int bufLen; - int lineNumber; - UT_hash_handle hh; /* Hashable structure */ -} FileCache; - -static FileCache* fileCache = NULL; -#if defined(_POSIX_) && !defined(NO_MUTEX) -#include -#if defined(G_HAS_CONSTRUCTORS) -static pthread_mutex_t m; -G_DEFINE_CONSTRUCTOR(initializeMutex) -static void initializeMutex(void) { - if (pthread_mutex_init(&m, NULL) != 0) { - ModelicaError("Initialization of mutex failed\n"); - } -} -G_DEFINE_DESTRUCTOR(destroyMutex) -static void destroyMutex(void) { - if (pthread_mutex_destroy(&m) != 0) { - ModelicaError("Destruction of mutex failed\n"); - } -} -#else -static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; -#endif -#define MUTEX_LOCK() pthread_mutex_lock(&m) -#define MUTEX_UNLOCK() pthread_mutex_unlock(&m) -#elif defined(_WIN32) && defined(G_HAS_CONSTRUCTORS) -#if !defined(WIN32_LEAN_AND_MEAN) -#define WIN32_LEAN_AND_MEAN -#endif -#include -static CRITICAL_SECTION cs; -#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA -#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(ModelicaInternal_initializeCS) -#endif -G_DEFINE_CONSTRUCTOR(ModelicaInternal_initializeCS) -static void ModelicaInternal_initializeCS(void) { - InitializeCriticalSection(&cs); -} -#ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA -#pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(ModelicaInternal_deleteCS) -#endif -G_DEFINE_DESTRUCTOR(ModelicaInternal_deleteCS) -static void ModelicaInternal_deleteCS(void) { - DeleteCriticalSection(&cs); -} -#define MUTEX_LOCK() EnterCriticalSection(&cs) -#define MUTEX_UNLOCK() LeaveCriticalSection(&cs) -#else -#define MUTEX_LOCK() -#define MUTEX_UNLOCK() -#endif - -#if !defined(LINE_BUFFER_LENGTH) -#define LINE_BUFFER_LENGTH (64) -#endif - -static void CacheFileForReading(FILE* fp, const char* fileName, int lineNumber, char* buf, int bufLen) { - FileCache* fv; - size_t len; - if (fileName == NULL) { - /* Do not add, close file */ - if (fp != NULL) { - fclose(fp); - } - return; - } - len = strlen(fileName); - MUTEX_LOCK(); - HASH_FIND(hh, fileCache, fileName, (unsigned)len, fv); - if (fv != NULL) { - fv->fp = fp; - fv->lineNumber = lineNumber; - fv->buf = buf; - fv->bufLen = bufLen; - } - else { - fv = (FileCache*)malloc(sizeof(FileCache)); - if (fv != NULL) { - char* key = (char*)malloc((len + 1)*sizeof(char)); - if (key != NULL) { - strcpy(key, fileName); - fv->fileName = key; - fv->fp = fp; - fv->lineNumber = lineNumber; - fv->buf = buf; - fv->bufLen = bufLen; - HASH_ADD_KEYPTR(hh, fileCache, key, (unsigned)len, fv); - if (NULL == fv->hh.tbl) { - free(key); - free(fv); - } - } - else { - free(fv); - } - } - } - MUTEX_UNLOCK(); -} - -static void CloseCachedFile(const char* fileName) { - FileCache* fv; - size_t len = strlen(fileName); - MUTEX_LOCK(); - HASH_FIND(hh, fileCache, fileName, (unsigned)len, fv); - if (fv != NULL) { - if (fv->fp != NULL) { - fclose(fv->fp); - } - free(fv->buf); - free(fv->fileName); - HASH_DEL(fileCache, fv); - free(fv); - } - MUTEX_UNLOCK(); -} - -static FILE* ModelicaStreams_openFileForReading(const char* fileName, int lineNumber, int* lineNumberOffset, char** buf, int* bufLen) { - /* Open text file for reading */ - FILE* fp; - FileCache* fv; - size_t len = strlen(fileName); - *lineNumberOffset = 0; - *buf = NULL; - *bufLen = LINE_BUFFER_LENGTH; - MUTEX_LOCK(); - HASH_FIND(hh, fileCache, fileName, (unsigned)len, fv); - /* Open file */ - if (fv != NULL) { - /* Cached value */ - if (fv->fp != NULL) { - if (lineNumber != 0 && lineNumber >= fv->lineNumber - 1) { - *lineNumberOffset = fv->lineNumber; - fp = fv->fp; - *buf = fv->buf; - *bufLen = fv->bufLen; - } - else { - if ( fseek(fv->fp, 0L, SEEK_SET) == 0 ) { - fp = fv->fp; - *buf = fv->buf; - *bufLen = fv->bufLen; - } - else { - fclose(fv->fp); - fp = NULL; - free(fv->buf); - } - } - fv->fp = NULL; - fv->buf = NULL; - } - else { - fp = NULL; - } - } - else { - fp = NULL; - } - MUTEX_UNLOCK(); - if (fp == NULL) { - fp = fopen(fileName, "r"); - if ( fp == NULL ) { - ModelicaFormatError("Not possible to open file \"%s\" for reading:\n" - "%s\n", fileName, strerror(errno)); - } - } - return fp; -} - -void ModelicaStreams_closeFile(_In_z_ const char* fileName) { - /* Close file */ - CloseCachedFile(fileName); /* Closes it */ -} - -static FILE* ModelicaStreams_openFileForWriting(const char* fileName) { - /* Open text file for writing (with append) */ - FILE* fp; - - /* Check fileName */ - if ( fileName[0] == '\0' ) { - ModelicaError("fileName is an empty string.\n" - "Opening of file is aborted\n"); - } - - /* Open file */ - ModelicaStreams_closeFile(fileName); - fp = fopen(fileName, "a"); - if ( fp == NULL ) { - ModelicaFormatError("Not possible to open file \"%s\" for writing:\n" - "%s\n", fileName, strerror(errno)); - } - return fp; -} - -static int readLine(_In_ char** buf, _In_ int* bufLen, _In_ FILE* fp) { - char* offset; - int oldBufLen; - - if (fgets(*buf, *bufLen, fp) == NULL) { - return EOF; - } - - do { - char* p; - char* tmp; - - if ((p = strchr(*buf, '\n')) != NULL) { - *p = '\0'; - return 0; - } - if ((p = memchr(*buf, 0, (size_t)(*bufLen - 1))) != NULL) { - return 1; - } - - oldBufLen = *bufLen; - *bufLen *= 2; - tmp = (char*)realloc(*buf, (size_t)*bufLen); - if (NULL == tmp) { - fclose(fp); - free(*buf); - ModelicaError("Memory allocation error\n"); - return 1; - } - *buf = tmp; - offset = &((*buf)[oldBufLen - 1]); - - } while (fgets(offset, oldBufLen + 1, fp)); - - return 0; -} - -/* --------------------- Modelica_Utilities.Streams ----------------------------------- */ - -void ModelicaInternal_print(_In_z_ const char* string, - _In_z_ const char* fileName) { - /* Write string to terminal or to file */ - if ( fileName[0] == '\0' ) { - /* Write string to terminal */ - ModelicaFormatMessage("%s\n", string); - } - else { - /* Write string to file */ - FILE* fp = ModelicaStreams_openFileForWriting(fileName); - if ( fputs(string,fp) < 0 ) { - goto Modelica_ERROR2; - } - if ( fputs("\n",fp) < 0 ) { - goto Modelica_ERROR2; - } - fclose(fp); - return; - -Modelica_ERROR2: - fclose(fp); - ModelicaFormatError("Error when writing string to file \"%s\":\n" - "%s\n", fileName, strerror(errno)); - } -} - -int ModelicaInternal_countLines(_In_z_ const char* fileName) { - /* Get number of lines of a file */ - int lineNumberOffset; - int bufLen; - char* buf; - int c; - int nLines = 0; - int start_of_line = 1; - /* If true, next character starts a new line. */ - - FILE* fp = ModelicaStreams_openFileForReading(fileName, 0, &lineNumberOffset, &buf, &bufLen); - - /* Count number of lines */ - while ((c = fgetc(fp)) != EOF) { - if (start_of_line) { - nLines++; - start_of_line = 0; - } - if (c == '\n') { - start_of_line = 1; - } - } - fclose(fp); - return nLines; -} - -void ModelicaInternal_readFile(_In_z_ const char* fileName, - _Out_ const char** string, size_t nLines) { - /* Read file into string vector string[nLines] */ - int lineNumberOffset; - int bufLen; - char* buf; - FILE* fp = ModelicaStreams_openFileForReading(fileName, 0, &lineNumberOffset, &buf, &bufLen); - char* line; - size_t iLines = 1; - - if (buf == NULL) { - buf = (char*)calloc(bufLen, sizeof(char)); - if (buf == NULL) { - goto Modelica_OOM_ERROR1; - } - } - - /* Read data from file */ - while (iLines <= nLines) { - readLine(&buf, &bufLen, fp); - - line = ModelicaAllocateStringWithErrorReturn(strlen(buf)); - if ( line == NULL ) { - goto Modelica_OOM_ERROR1; - } - - strcpy(line, buf); - string[iLines - 1] = line; - iLines++; - } - fclose(fp); - free(buf); - return; - - /* Out-of-memory error */ -Modelica_OOM_ERROR1: - fclose(fp); - free(buf); - ModelicaFormatError("Error when reading line %lu from file \"%s\":\n" - "Not enough memory to allocate string for reading line.", - (unsigned long)iLines, fileName); -} - -_Ret_z_ const char* ModelicaInternal_readLine(_In_z_ const char* fileName, - int lineNumber, _Out_ int* endOfFile) { - /* Read line lineNumber from file fileName */ - int lineNumberOffset; - int bufLen; - char* buf; - FILE* fp; - char* line; - int iLine; - - fp = ModelicaStreams_openFileForReading(fileName, lineNumber - 1, &lineNumberOffset, &buf, &bufLen); - - if (feof(fp)) { - goto END_OF_FILE; - } - - if (buf == NULL) { - buf = (char*)calloc(bufLen, sizeof(char)); - if (buf == NULL) { - goto Modelica_OOM_ERROR2; - } - } - - for (iLine = 0; iLine < lineNumber - lineNumberOffset; iLine++) { - int readError = readLine(&buf, &bufLen, fp); - if (readError == EOF && iLine == lineNumber - lineNumberOffset - 1) { - goto END_OF_FILE; - } - } - - line = ModelicaAllocateStringWithErrorReturn(strlen(buf)); - if (line == NULL) { - goto Modelica_OOM_ERROR2; - } - - strcpy(line, buf); - CacheFileForReading(fp, fileName, lineNumber, buf, bufLen); - *endOfFile = 0; - return line; - - /* End-of-File or error */ -END_OF_FILE: - fclose(fp); - CloseCachedFile(fileName); - *endOfFile = 1; - line = ModelicaAllocateString(0); - line[0] = '\0'; - return line; - -Modelica_OOM_ERROR2: - fclose(fp); - CloseCachedFile(fileName); - ModelicaFormatError("Error when reading line %i from file \"%s\":\n" - "Not enough memory to allocate string for reading line.", lineNumber, fileName); - return ""; -} - -/* --------------------- Modelica_Utilities.System ------------------------------------ */ - -void ModelicaInternal_chdir(_In_z_ const char* directoryName) { - /* Change current working directory */ -#if defined(__WATCOMC__) || defined(__LCC__) - int result = chdir(directoryName); -#elif defined(__BORLANDC__) - int result = chdir(directoryName); -#elif defined(_WIN32) - int result = _chdir(directoryName); -#elif defined(_POSIX_) || defined(__GNUC__) - int result = chdir(directoryName); -#else - ModelicaNotExistError("ModelicaInternal_chdir"); -#endif -#if defined(__WATCOMC__) || defined(__LCC__) || defined(__BORLANDC__) || defined(_WIN32) || defined(_POSIX_) || defined(__GNUC__) - if (result != 0) { - ModelicaFormatError("Not possible to change current working directory to\n" - "\"%s\":\n%s", directoryName, strerror(errno)); - } -#endif -} - -_Ret_z_ const char* ModelicaInternal_getcwd(int dummy) { - const char* cwd; - char* directory; - -#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_POSIX_) || defined(__GNUC__) - char localbuf[BUFFER_LENGTH]; - cwd = getcwd(localbuf, sizeof(localbuf)); -#elif defined(_WIN32) - char localbuf[BUFFER_LENGTH]; - cwd = _getcwd(localbuf, sizeof(localbuf)); -#else - ModelicaNotExistError("ModelicaInternal_getcwd"); - cwd = ""; -#endif -#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_WIN32) || defined(_POSIX_) || defined(__GNUC__) - if (cwd == NULL) { - ModelicaFormatError("Not possible to get current working directory:\n%s", - strerror(errno)); - cwd = ""; - } -#endif - directory = ModelicaAllocateString(strlen(cwd)); - strcpy(directory, cwd); - ModelicaConvertToUnixDirectorySeparator(directory); - return directory; -} - -void ModelicaInternal_getenv(_In_z_ const char* name, int convertToSlash, - _Out_ const char** content, _Out_ int* exist) { - /* Get content of environment variable */ - char* result; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - char* value; - size_t len = 0; - errno_t err = _dupenv_s(&value, &len, name); - if (err) { - value = NULL; - } -#else - char* value = getenv(name); -#endif - - if (value == NULL) { - result = ModelicaAllocateString(0); - result[0] = '\0'; - *exist = 0; - } - else { -#if defined(_MSC_VER) && _MSC_VER >= 1400 - result = ModelicaAllocateStringWithErrorReturn(len); /* (len - 1) actually is sufficient */ - if (result) { -#else - result = ModelicaAllocateString(strlen(value)); -#endif - strcpy(result, value); - if ( convertToSlash == 1 ) { - ModelicaConvertToUnixDirectorySeparator(result); - } - *exist = 1; -#if defined(_MSC_VER) && _MSC_VER >= 1400 - free(value); - } - else { - free(value); - ModelicaFormatError("Not enough memory to allocate string for copying " - "environment variable \"%s\".\n", name); - } -#endif - } - *content = result; -} - -#if !defined(_MSC_VER) && !defined(__WATCOMC__) && !defined(__BORLANDC__) && !defined(_WIN32) && defined(_POSIX_) && _POSIX_VERSION < 200112L -static char envBuf[BUFFER_LENGTH]; -#endif - -void ModelicaInternal_setenv(_In_z_ const char* name, - _In_z_ const char* value, int convertFromSlash) { - /* Set environment variable */ -#if defined(_MSC_VER) && _MSC_VER >= 1400 - errno_t err; - if (1 == convertFromSlash) { - char* buf = (char*)malloc((strlen(value) + 1)*sizeof(char)); - if (NULL != buf) { - strcpy(buf, value); - ModelicaConvertFromUnixDirectorySeparator(buf); - err = _putenv_s(name, buf); - free(buf); - } - else { - ModelicaError("Memory allocation error\n"); - } - } - else { - err = _putenv_s(name, value); - } - if (0 != err) { - ModelicaFormatError("Not possible to set environment variable:\n%s", - strerror(err)); - } -#elif defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_WIN32) - char* buf = (char*)malloc((strlen(name) + strlen(value) + 2)*sizeof(char)); - if (NULL != buf) { - int result; - - strcpy(buf, name); - strcat(buf, "="); - strcat(buf, value); - - if (1 == convertFromSlash) { - ModelicaConvertFromUnixDirectorySeparator(&buf[strlen(name) + 1]); - } -#if defined(__WATCOMC__) || defined(__BORLANDC__) - result = putenv(buf); -#else - result = _putenv(buf); -#endif - free(buf); - if (0 != result) { - ModelicaFormatError("Environment variable\n" - "\"%s\"=\"%s\"\n" - "cannot be set: %s", name, value, strerror(errno)); - } - } - else { - ModelicaError("Memory allocation error\n"); - } -#elif defined(_POSIX_) && _POSIX_VERSION >= 200112L - int result; - if (1 == convertFromSlash) { - char* buf = (char*)malloc((strlen(value) + 1)*sizeof(char)); - if (NULL != buf) { - strcpy(buf, value); - ModelicaConvertFromUnixDirectorySeparator(buf); - result = setenv(name, buf, 1); - free(buf); - } - else { - ModelicaError("Memory allocation error\n"); - } - } - else { - result = setenv(name, value, 1); - } - if (0 != result) { - ModelicaFormatError("Not possible to set environment variable:\n%s", - strerror(errno)); - } -#elif defined(_POSIX_) - /* Restriction: This legacy implementation only works on exactly one - environment variable since a single buffer is used. */ - if (strlen(name) + strlen(value) + 2 > sizeof(envBuf)) { - ModelicaFormatError("Environment variable\n" - "\"%s\"=\"%s\"\n" - "cannot be set, because the internal buffer\n" - "in file \"ModelicaInternal.c\" is too small (= %d)", - name, value, sizeof(envBuf)); - } - strcpy(envBuf, name); - strcat(envBuf, "="); - strcat(envBuf, value); - - if (1 == convertFromSlash) { - ModelicaConvertFromUnixDirectorySeparator(&envBuf[strlen(name) + 1]); - } - - if (putenv(envBuf) != 0) { - ModelicaFormatError("Environment variable\n" - "\"%s\"=\"%s\"\n" - "cannot be set: %s", name, value, strerror(errno)); - } -#else - ModelicaNotExistError("ModelicaInternal_setenv"); -#endif -} - -#endif - -/* Low-level time and pid functions */ -/* Some parts from: http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking */ - -#if !defined(NO_PID) - #if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_WIN32) - #include - #elif defined(NO_FILE_SYSTEM) && (defined(_POSIX_) || defined(__GNUC__)) - #include - #include - #endif -#endif - -#if !defined(NO_TIME) - #include - #if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(_WIN32) - #include - #elif defined(_POSIX_) || defined(__GNUC__) - #include - #endif -#endif - -int ModelicaInternal_getpid(void) { -#if defined(NO_PID) - return 0; -#else -#if defined(_POSIX_) || defined(__GNUC__) || defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__LCC__) - return getpid(); -#else - return _getpid(); -#endif -#endif -} - -void ModelicaInternal_getTime(_Out_ int* ms, _Out_ int* sec, _Out_ int* min, _Out_ int* hour, - _Out_ int* mday, _Out_ int* mon, _Out_ int* year) { -#if defined(NO_TIME) - *ms = 0; - *sec = 0; - *min = 0; - *hour = 0; - *mday = 0; - *mon = 0; - *year = 0; -#else - struct tm* tlocal; - time_t calendarTime; - int ms0; -#if defined(_POSIX_) || (defined(_MSC_VER) && _MSC_VER >= 1400) - struct tm tres; -#endif - - time(&calendarTime); /* Retrieve sec time */ -#if defined(_POSIX_) - tlocal = localtime_r(&calendarTime, &tres); /* Time fields in local time zone */ -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - localtime_s(&tres, &calendarTime); /* Time fields in local time zone */ - tlocal = &tres; -#else - tlocal = localtime(&calendarTime); /* Time fields in local time zone */ -#endif - - /* Get millisecond resolution depending on platform */ -#if defined(_WIN32) - { -#if defined(__BORLANDC__) - struct timeb timebuffer; -#else - struct _timeb timebuffer; -#endif -#if defined(__BORLANDC__) || defined(__LCC__) - ftime( &timebuffer ); /* Retrieve ms time */ -#else - _ftime( &timebuffer ); /* Retrieve ms time */ -#endif - ms0 = (int)(timebuffer.millitm); /* Convert unsigned int to int */ - } -#else - { - struct timeval tv; - gettimeofday(&tv, NULL); - ms0 = (int)(tv.tv_usec/1000); /* Convert microseconds to milliseconds */ - } -#endif - - /* Do not memcpy as you do not know which sizes are in the struct */ - *ms = ms0; - *sec = tlocal->tm_sec; - *min = tlocal->tm_min; - *hour = tlocal->tm_hour; - *mday = tlocal->tm_mday; - *mon = 1 + tlocal->tm_mon; /* Correct for month starting at 1 */ - *year = 1900 + tlocal->tm_year; /* Correct for 4-digit year */ -#endif -} diff --git a/ModelicaExternalC/C-Sources/ModelicaInternal.h b/ModelicaExternalC/C-Sources/ModelicaInternal.h deleted file mode 100644 index f6ee944d0..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaInternal.h +++ /dev/null @@ -1,122 +0,0 @@ -/* ModelicaInternal.h - External functions header for Modelica.Utilities - - Copyright (C) 2002-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* The following #define's are available. - - NO_FILE_SYSTEM : A file system is not present (e.g. on dSPACE or xPC). - NO_MUTEX : Pthread mutex is not present (e.g. on dSPACE) - NO_PID : Function getpid is not present (e.g. on dSPACE) - NO_TIME : Function gettimeofday is not present (e.g. on dSPACE) - MODELICA_EXPORT: Prefix used for function calls. If not defined, blank is used - Useful definition: - - "__declspec(dllexport)" if included in a DLL and the - functions shall be visible outside of the DLL -*/ - -#ifndef MODELICA_INTERNAL_H_ -#define MODELICA_INTERNAL_H_ - -#include - -#if !defined(MODELICA_EXPORT) -#if defined(__cplusplus) -#define MODELICA_EXPORT extern "C" -#else -#define MODELICA_EXPORT -#endif -#endif - -/* - * Non-null pointers and esp. null-terminated strings need to be passed to - * external functions. - * - * The following macros handle nonnull attributes for GNU C and Microsoft SAL. - */ -#undef MODELICA_NONNULLATTR -#undef MODELICA_RETURNNONNULLATTR -#if defined(__GNUC__) -#define MODELICA_NONNULLATTR __attribute__((nonnull)) -#if defined(__GNUC_MINOR__) && (__GNUC__ > 3 && __GNUC_MINOR__ > 8) -#define MODELICA_RETURNNONNULLATTR __attribute__((returns_nonnull)) -#else -#define MODELICA_RETURNNONNULLATTR -#endif -#elif defined(__ATTR_SAL) -#define MODELICA_NONNULLATTR -#define MODELICA_RETURNNONNULLATTR _Ret_z_ /* _Ret_notnull_ and null-terminated */ -#else -#define MODELICA_NONNULLATTR -#define MODELICA_RETURNNONNULLATTR -#endif -#if !defined(__ATTR_SAL) -#undef _In_ -#undef _In_z_ -#undef _Out_ -#undef _Ret_z_ -#define _In_ -#define _In_z_ -#define _Out_ -#define _Ret_z_ -#endif - -MODELICA_EXPORT void ModelicaInternal_mkdir(_In_z_ const char* directoryName) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_rmdir(_In_z_ const char* directoryName) MODELICA_NONNULLATTR; -MODELICA_EXPORT int ModelicaInternal_stat(_In_z_ const char* name) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_rename(_In_z_ const char* oldName, - _In_z_ const char* newName) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_removeFile(_In_z_ const char* file) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_copyFile(_In_z_ const char* oldFile, - _In_z_ const char* newFile) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_readDirectory(_In_z_ const char* directory, int nFiles, - _Out_ const char** files) MODELICA_NONNULLATTR; -MODELICA_EXPORT int ModelicaInternal_getNumberOfFiles(_In_z_ const char* directory) MODELICA_NONNULLATTR; -MODELICA_EXPORT MODELICA_RETURNNONNULLATTR const char* ModelicaInternal_fullPathName( - _In_z_ const char* name) MODELICA_NONNULLATTR; -MODELICA_EXPORT MODELICA_RETURNNONNULLATTR const char* ModelicaInternal_temporaryFileName(void); -MODELICA_EXPORT void ModelicaStreams_closeFile(_In_z_ const char* fileName) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_print(_In_z_ const char* string, - _In_z_ const char* fileName) MODELICA_NONNULLATTR; -MODELICA_EXPORT int ModelicaInternal_countLines(_In_z_ const char* fileName) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_readFile(_In_z_ const char* fileName, - _Out_ const char** string, size_t nLines) MODELICA_NONNULLATTR; -MODELICA_EXPORT MODELICA_RETURNNONNULLATTR const char* ModelicaInternal_readLine(_In_z_ const char* fileName, - int lineNumber, _Out_ int* endOfFile) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_chdir(_In_z_ const char* directoryName) MODELICA_NONNULLATTR; -MODELICA_EXPORT MODELICA_RETURNNONNULLATTR const char* ModelicaInternal_getcwd(int dummy); -MODELICA_EXPORT void ModelicaInternal_getenv(_In_z_ const char* name, int convertToSlash, - _Out_ const char** content, _Out_ int* exist) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_setenv(_In_z_ const char* name, - _In_z_ const char* value, int convertFromSlash) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaInternal_getTime(_Out_ int* ms, _Out_ int* sec, _Out_ int* min, _Out_ int* hour, - _Out_ int* mday, _Out_ int* mon, _Out_ int* year) MODELICA_NONNULLATTR; -MODELICA_EXPORT int ModelicaInternal_getpid(void); - -#endif diff --git a/ModelicaExternalC/C-Sources/ModelicaMatIO.c b/ModelicaExternalC/C-Sources/ModelicaMatIO.c deleted file mode 100644 index 1c9893e59..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaMatIO.c +++ /dev/null @@ -1,15833 +0,0 @@ -/* ModelicaMatIO.c - MAT file I/O functions - - Copyright (C) 2013-2021, Modelica Association and contributors - Copyright (C) 2005-2013, Christopher C. Hulbert - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* This file was created by concatenation of the following C source files of the - MAT file I/O library from : - - endian.c - inflate.c - io.c - read_data.c - mat.c - mat4.c - mat5.c - mat73.c - matvar_cell.c - matvar_struct.c -*/ - -/* By default v4 and v6 MAT-files are supported. The v7 and v7.3 MAT-file - formats require additional preprocessor options and third-party libraries. - The following #define's are available. - - NO_FILE_SYSTEM: A file system is not present (e.g. on dSPACE or xPC). - NO_LOCALE : locale.h is not present (e.g. on AVR). - HAVE_ZLIB=1 : Enables the support of v7 MAT-files - The zlib (>= v1.2.3) library is required. - HAVE_HDF5=1 : Enables the support of v7.3 MAT-files - The hdf5 (>= v1.8) library is required. -*/ - -#if !defined(NO_FILE_SYSTEM) -#if defined(__gnu_linux__) -#define _GNU_SOURCE 1 -#elif defined(__MINGW32__) && !defined(__USE_MINGW_ANSI_STDIO) -#define __USE_MINGW_ANSI_STDIO 1 -#endif -#include -#include "ModelicaUtilities.h" - -/* ------------------------------- - * ---------- endian.c - * ------------------------------- - */ -/** @file endian.c - * @brief Functions to handle endian specifics - */ -#include -#ifndef MATIO_PRIVATE_H -#define MATIO_PRIVATE_H - -/* Extended sparse matrix data types */ -/* #undef EXTENDED_SPARSE */ - -/* Define to 1 if you have the header file. */ -#if defined(_WIN32) -#if defined(_MSC_VER) && _MSC_VER >= 1800 -#define HAVE_INTTYPES_H 1 -#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) -#define HAVE_INTTYPES_H 1 -#else -#undef HAVE_INTTYPES_H -#endif -#elif defined(__GNUC__) -#define HAVE_INTTYPES_H 1 -#else -#undef HAVE_INTTYPES_H -#endif - -/* Define to 1 if you have the header file. */ -#if defined(_MSC_VER) && _MSC_VER >= 1600 -#define HAVE_INTSAFE_H 1 -#else -#undef HAVE_INTSAFE_H -#endif - -#if !defined(__BORLANDC__) && !defined(__LCC__) && !(defined(_MSC_VER) && _MSC_VER < 1400) -#define HAVE_SAFE_MATH 1 -#else -#undef HAVE_SAFE_MATH -#endif - -#if !defined(NO_LOCALE) -/* Define to 1 if you have the `localeconv' function. */ -#define HAVE_LOCALECONV 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 -#endif - -/* Define to 1 if the system has the type `long double'. */ -#if defined(_WIN32) -#if defined(__WATCOMC__) || (defined(_MSC_VER) && _MSC_VER >= 1300) -#define HAVE_LONG_DOUBLE 1 -#endif -#endif -#if defined(__GNUC__) -#define HAVE_LONG_DOUBLE 1 -#endif - -/* Define to 1 if the system has the type `long long int'. */ -#if defined(_WIN32) -#if defined(__WATCOMC__) || (defined(_MSC_VER) && _MSC_VER >= 1300) -#define HAVE_LONG_LONG_INT 1 -#endif -#endif -#if defined(__GNUC__) && __STDC_VERSION__ >= 199901L -#define HAVE_LONG_LONG_INT 1 -#endif - -/* Define to 1 if the system has the type `ptrdiff_t'. */ -#define HAVE_PTRDIFF_T 1 - -/* Define to 1 if you have a C99 compliant `snprintf' function. */ -#if defined(STDC99) -#define HAVE_SNPRINTF 1 -#elif defined(__MINGW32__) || defined(__CYGWIN__) -#if __STDC_VERSION__ >= 199901L -#define HAVE_SNPRINTF 1 -#endif -#elif defined(__WATCOMC__) -#define HAVE_SNPRINTF 1 -#elif defined(__TURBOC__) && __TURBOC__ >= 0x550 -#define HAVE_SNPRINTF 1 -#elif defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -#define HAVE_SNPRINTF 1 -#elif defined(_MSC_VER) && _MSC_VER >= 1900 -#define HAVE_SNPRINTF 1 -#else -#undef HAVE_SNPRINTF -#endif - -/* Define to 1 if you have the header file. */ -#define HAVE_STDARG_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDDEF_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if `decimal_point' is member of `struct lconv'. */ -#define HAVE_STRUCT_LCONV_DECIMAL_POINT 1 - -/* Define to 1 if `thousands_sep' is member of `struct lconv'. */ -#define HAVE_STRUCT_LCONV_THOUSANDS_SEP 1 - -/* Define to 1 if the system has the type `unsigned long long int'. */ -#if defined(_WIN32) -#if defined(__WATCOMC__) || (defined(_MSC_VER) && _MSC_VER >= 1300) -#define HAVE_UNSIGNED_LONG_LONG_INT 1 -#endif -#endif -#if defined(__GNUC__) && __STDC_VERSION__ >= 199901L -#define HAVE_UNSIGNED_LONG_LONG_INT 1 -#endif - -/* Define to 1 if you have the `va_copy' function or macro. */ -#if defined(__GNUC__) && __STDC_VERSION__ >= 199901L -#define HAVE_VA_COPY 1 -#elif defined(_MSC_VER) && _MSC_VER >= 1800 -#define HAVE_VA_COPY 1 -#elif defined(__WATCOMC__) -#define HAVE_VA_COPY 1 -#else -#undef HAVE_VA_COPY -#endif - -/* Define to 1 if you have the `__va_copy' function or macro. */ -#if defined(__GNUC__) -#define HAVE___VA_COPY 1 -#elif defined(__WATCOMC__) -#define HAVE___VA_COPY 1 -#else -#undef HAVE___VA_COPY -#endif - -/* Platform */ -#if defined(_MSC_VER) && defined(_WIN64) -#define MATIO_PLATFORM "x86_64-pc-windows" -#elif defined(_MSC_VER) && defined(_WIN32) -#define MATIO_PLATFORM "i686-pc-windows" -#else -#define MATIO_PLATFORM "UNKNOWN" -#endif - -/* Fixed types in safe-math.h disabled */ -#define PSNIP_SAFE_NO_FIXED 1 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Z prefix */ -#undef Z_PREFIX - -#include "ModelicaMatIO.h" - -#if HAVE_SAFE_MATH -#include "safe-math.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__GLIBC__) -#include -#endif - -#if HAVE_INTTYPES_H -#define __STDC_FORMAT_MACROS -#include -#endif - -#if HAVE_ZLIB -#define ZLIB_BYTE_PTR(a) ((Bytef *)(a)) -#include -#endif - -#if HAVE_HDF5 -#include -#endif - -#if ( defined(_WIN64) || defined(_WIN32) ) && !defined(__CYGWIN__) -#include -#endif - -#if defined(_MSC_VER) || defined(__MINGW32__) -#define SIZE_T_FMTSTR "Iu" -#else -#define SIZE_T_FMTSTR "zu" -#endif - -#ifndef INT32_MAX -#define INT32_MAX INT_MAX -#endif - -#ifndef UINT32_MAX -#ifdef UINT_MAX -#define UINT32_MAX UINT_MAX -#else -#define UINT32_MAX INT_MAX -#endif -#endif - -#if !defined(READ_BLOCK_SIZE) -#define READ_BLOCK_SIZE (256) -#endif - -#define _CAT(X, Y) X##Y -#define CAT(X, Y) _CAT(X, Y) - -/** @if mat_devman - * @brief Matlab MAT File information - * - * Contains information about a Matlab MAT file - * @ingroup mat_internal - * @endif - */ -struct _mat_t -{ - void *fp; /**< File pointer for the MAT file */ - char *header; /**< MAT file header string */ - char *subsys_offset; /**< Offset */ - char *filename; /**< Filename of the MAT file */ - int version; /**< MAT file version */ - int byteswap; /**< 1 if byte swapping is required, 0 otherwise */ - int mode; /**< Access mode */ - long bof; /**< Beginning of file not including any header */ - size_t next_index; /**< Index/File position of next variable to read */ - size_t num_datasets; /**< Number of datasets in the file */ -#if HAVE_HDF5 - hid_t refs_id; /**< Id of the /#refs# group in HDF5 */ -#endif - char **dir; /**< Names of the datasets in the file */ -}; - -/** @if mat_devman - * @brief internal structure for MAT variables - * @ingroup mat_internal - * @endif - */ -struct matvar_internal -{ -#if HAVE_HDF5 - char *hdf5_name; /**< Name */ - hobj_ref_t hdf5_ref; /**< Reference */ - hid_t id; /**< Id */ -#endif - long datapos; /**< Offset from the beginning of the MAT file to the data */ - unsigned num_fields; /**< Number of fields */ - char **fieldnames; /**< Pointer to fieldnames */ -#if HAVE_ZLIB - z_streamp z; /**< zlib compression state */ - void *data; /**< Inflated data array */ -#endif -}; - -/* snprintf.c */ -#if !HAVE_SNPRINTF -int rpl_snprintf(char *, size_t, const char *, ...); -#define mat_snprintf rpl_snprintf -#else -#define mat_snprintf snprintf -#endif /* !HAVE_SNPRINTF */ - -/* endian.c */ -static double Mat_doubleSwap(double *a); -static float Mat_floatSwap(float *a); -#ifdef HAVE_MATIO_INT64_T -static mat_int64_t Mat_int64Swap(mat_int64_t *a); -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T -static mat_uint64_t Mat_uint64Swap(mat_uint64_t *a); -#endif /* HAVE_MATIO_UINT64_T */ -static mat_int32_t Mat_int32Swap(mat_int32_t *a); -static mat_uint32_t Mat_uint32Swap(mat_uint32_t *a); -static mat_int16_t Mat_int16Swap(mat_int16_t *a); -static mat_uint16_t Mat_uint16Swap(mat_uint16_t *a); - -/* read_data.c */ -static size_t ReadDoubleData(mat_t *mat, double *data, enum matio_types data_type, size_t len); -static size_t ReadSingleData(mat_t *mat, float *data, enum matio_types data_type, size_t len); -#ifdef HAVE_MATIO_INT64_T -static size_t ReadInt64Data(mat_t *mat, mat_int64_t *data, enum matio_types data_type, size_t len); -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T -static size_t ReadUInt64Data(mat_t *mat, mat_uint64_t *data, enum matio_types data_type, - size_t len); -#endif /* HAVE_MATIO_UINT64_T */ -static size_t ReadInt32Data(mat_t *mat, mat_int32_t *data, enum matio_types data_type, size_t len); -static size_t ReadUInt32Data(mat_t *mat, mat_uint32_t *data, enum matio_types data_type, - size_t len); -static size_t ReadInt16Data(mat_t *mat, mat_int16_t *data, enum matio_types data_type, size_t len); -static size_t ReadUInt16Data(mat_t *mat, mat_uint16_t *data, enum matio_types data_type, - size_t len); -static size_t ReadInt8Data(mat_t *mat, mat_int8_t *data, enum matio_types data_type, size_t len); -static size_t ReadUInt8Data(mat_t *mat, mat_uint8_t *data, enum matio_types data_type, size_t len); -static size_t ReadCharData(mat_t *mat, void *data, enum matio_types data_type, size_t len); -static int ReadDataSlab1(mat_t *mat, void *data, enum matio_classes class_type, - enum matio_types data_type, int start, int stride, int edge); -static int ReadDataSlab2(mat_t *mat, void *data, enum matio_classes class_type, - enum matio_types data_type, size_t *dims, int *start, int *stride, - int *edge); -static int ReadDataSlabN(mat_t *mat, void *data, enum matio_classes class_type, - enum matio_types data_type, int rank, size_t *dims, int *start, - int *stride, int *edge); -#if HAVE_ZLIB -static int ReadCompressedDoubleData(mat_t *mat, z_streamp z, double *data, - enum matio_types data_type, int len); -static int ReadCompressedSingleData(mat_t *mat, z_streamp z, float *data, - enum matio_types data_type, int len); -#ifdef HAVE_MATIO_INT64_T -static int ReadCompressedInt64Data(mat_t *mat, z_streamp z, mat_int64_t *data, - enum matio_types data_type, int len); -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T -static int ReadCompressedUInt64Data(mat_t *mat, z_streamp z, mat_uint64_t *data, - enum matio_types data_type, int len); -#endif /* HAVE_MATIO_UINT64_T */ -static int ReadCompressedInt32Data(mat_t *mat, z_streamp z, mat_int32_t *data, - enum matio_types data_type, int len); -static int ReadCompressedUInt32Data(mat_t *mat, z_streamp z, mat_uint32_t *data, - enum matio_types data_type, int len); -static int ReadCompressedInt16Data(mat_t *mat, z_streamp z, mat_int16_t *data, - enum matio_types data_type, int len); -static int ReadCompressedUInt16Data(mat_t *mat, z_streamp z, mat_uint16_t *data, - enum matio_types data_type, int len); -static int ReadCompressedInt8Data(mat_t *mat, z_streamp z, mat_int8_t *data, - enum matio_types data_type, int len); -static int ReadCompressedUInt8Data(mat_t *mat, z_streamp z, mat_uint8_t *data, - enum matio_types data_type, int len); -static int ReadCompressedCharData(mat_t *mat, z_streamp z, void *data, enum matio_types data_type, - size_t len); -static int ReadCompressedDataSlab1(mat_t *mat, z_streamp z, void *data, - enum matio_classes class_type, enum matio_types data_type, - int start, int stride, int edge); -static int ReadCompressedDataSlab2(mat_t *mat, z_streamp z, void *data, - enum matio_classes class_type, enum matio_types data_type, - size_t *dims, int *start, int *stride, int *edge); -static int ReadCompressedDataSlabN(mat_t *mat, z_streamp z, void *data, - enum matio_classes class_type, enum matio_types data_type, - int rank, size_t *dims, int *start, int *stride, int *edge); - -/* inflate.c */ -static int InflateSkip(mat_t *mat, z_streamp z, int nBytes, size_t *bytesread); -static int InflateSkipData(mat_t *mat, z_streamp z, enum matio_types data_type, int len); -static int InflateRankDims(mat_t *mat, z_streamp z, void *buf, size_t nBytes, mat_uint32_t **dims, - size_t *bytesread); -static int Inflate(mat_t *mat, z_streamp z, void *buf, unsigned int nBytes, size_t *bytesread); -static int InflateData(mat_t *mat, z_streamp z, void *buf, unsigned int nBytes); -#endif - -/* mat.c */ -static mat_complex_split_t *ComplexMalloc(size_t nbytes); -static void ComplexFree(mat_complex_split_t *complex_data); -static enum matio_types ClassType2DataType(enum matio_classes class_type); -static int Add(size_t *res, size_t a, size_t b); -static int Mul(size_t *res, size_t a, size_t b); -static int Mat_MulDims(const matvar_t *matvar, size_t *nelems); -static int Read(void *buf, size_t size, size_t count, FILE *fp, size_t *bytesread); -static int IsEndOfFile(FILE *fp, long *fpos); - -/* io.c */ -#if defined(_WIN32) && defined(_MSC_VER) -static wchar_t *utf82u(const char *src); -#endif - -#endif - -/** @brief swap the bytes @c a and @c b - * @ingroup mat_internal - */ -#define swap(a, b) \ - a ^= b; \ - b ^= a; \ - a ^= b - -#ifdef HAVE_MATIO_INT64_T -/** @brief swap the bytes of a 64-bit signed integer - * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer - */ -static mat_int64_t -Mat_int64Swap(mat_int64_t *a) -{ - union { - mat_int8_t i1[8]; - mat_int64_t i8; - } tmp; - - tmp.i8 = *a; - - swap(tmp.i1[0], tmp.i1[7]); - swap(tmp.i1[1], tmp.i1[6]); - swap(tmp.i1[2], tmp.i1[5]); - swap(tmp.i1[3], tmp.i1[4]); - - *a = tmp.i8; - - return *a; -} -#endif /* HAVE_MATIO_INT64_T */ - -#ifdef HAVE_MATIO_UINT64_T -/** @brief swap the bytes of a 64-bit unsigned integer - * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer - */ -static mat_uint64_t -Mat_uint64Swap(mat_uint64_t *a) -{ - union { - mat_uint8_t i1[8]; - mat_uint64_t i8; - } tmp; - - tmp.i8 = *a; - - swap(tmp.i1[0], tmp.i1[7]); - swap(tmp.i1[1], tmp.i1[6]); - swap(tmp.i1[2], tmp.i1[5]); - swap(tmp.i1[3], tmp.i1[4]); - - *a = tmp.i8; - - return *a; -} -#endif /* HAVE_MATIO_UINT64_T */ - -/** @brief swap the bytes of a 32-bit signed integer - * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer - */ -static mat_int32_t -Mat_int32Swap(mat_int32_t *a) -{ - union { - mat_int8_t i1[4]; - mat_int32_t i4; - } tmp; - - tmp.i4 = *a; - - swap(tmp.i1[0], tmp.i1[3]); - swap(tmp.i1[1], tmp.i1[2]); - - *a = tmp.i4; - - return *a; -} - -/** @brief swap the bytes of a 32-bit unsigned integer - * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer - */ -static mat_uint32_t -Mat_uint32Swap(mat_uint32_t *a) -{ - union { - mat_uint8_t i1[4]; - mat_uint32_t i4; - } tmp; - - tmp.i4 = *a; - - swap(tmp.i1[0], tmp.i1[3]); - swap(tmp.i1[1], tmp.i1[2]); - - *a = tmp.i4; - - return *a; -} - -/** @brief swap the bytes of a 16-bit signed integer - * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer - */ -static mat_int16_t -Mat_int16Swap(mat_int16_t *a) -{ - union { - mat_int8_t i1[2]; - mat_int16_t i2; - } tmp; - - tmp.i2 = *a; - - swap(tmp.i1[0], tmp.i1[1]); - - *a = tmp.i2; - return *a; -} - -/** @brief swap the bytes of a 16-bit unsigned integer - * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer - */ -static mat_uint16_t -Mat_uint16Swap(mat_uint16_t *a) -{ - union { - mat_uint8_t i1[2]; - mat_uint16_t i2; - } tmp; - - tmp.i2 = *a; - - swap(tmp.i1[0], tmp.i1[1]); - - *a = tmp.i2; - return *a; -} - -/** @brief swap the bytes of a 4 byte single-precision float - * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer - */ -static float -Mat_floatSwap(float *a) -{ - union { - char i1[4]; - float r4; - } tmp; - - tmp.r4 = *a; - - swap(tmp.i1[0], tmp.i1[3]); - swap(tmp.i1[1], tmp.i1[2]); - - *a = tmp.r4; - return *a; -} - -/** @brief swap the bytes of a 4 or 8 byte double-precision float - * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer - */ -static double -Mat_doubleSwap(double *a) -{ -#ifndef SIZEOF_DOUBLE -#define SIZEOF_DOUBLE 8 -#endif - - union { - char a[SIZEOF_DOUBLE]; - double b; - } tmp; - - tmp.b = *a; - -#if SIZEOF_DOUBLE == 4 - swap(tmp.a[0], tmp.a[3]); - swap(tmp.a[1], tmp.a[2]); -#elif SIZEOF_DOUBLE == 8 - swap(tmp.a[0], tmp.a[7]); - swap(tmp.a[1], tmp.a[6]); - swap(tmp.a[2], tmp.a[5]); - swap(tmp.a[3], tmp.a[4]); -#elif SIZEOF_DOUBLE == 16 - swap(tmp.a[0], tmp.a[15]); - swap(tmp.a[1], tmp.a[14]); - swap(tmp.a[2], tmp.a[13]); - swap(tmp.a[3], tmp.a[12]); - swap(tmp.a[4], tmp.a[11]); - swap(tmp.a[5], tmp.a[10]); - swap(tmp.a[6], tmp.a[9]); - swap(tmp.a[7], tmp.a[8]); -#endif - *a = tmp.b; - return *a; -} - -/* ------------------------------- - * ---------- inflate.c - * ------------------------------- - */ -/** @file inflate.c - * @brief Functions to inflate data/tags - * @ingroup MAT - */ - -#if HAVE_ZLIB - -/** @cond mat_devman */ - -/** @brief Inflate the data until @c nBytes of uncompressed data has been - * inflated - * - * @ingroup mat_internal - * @param mat Pointer to the MAT file - * @param z zlib compression stream - * @param nBytes Number of uncompressed bytes to skip - * @param[out] bytesread Number of bytes read from the file - * @retval 0 on success - - */ -static int -InflateSkip(mat_t *mat, z_streamp z, int nBytes, size_t *bytesread) -{ - mat_uint8_t comp_buf[READ_BLOCK_SIZE], uncomp_buf[READ_BLOCK_SIZE]; - int n, err = MATIO_E_NO_ERROR, cnt = 0; - - if ( nBytes < 1 ) - return MATIO_E_NO_ERROR; - - n = nBytes < READ_BLOCK_SIZE ? nBytes : READ_BLOCK_SIZE; - if ( !z->avail_in ) { - size_t nbytes = fread(comp_buf, 1, n, (FILE *)mat->fp); - if ( 0 == nbytes ) { - return err; - } - if ( NULL != bytesread ) { - *bytesread += nbytes; - } - z->avail_in = (uInt)nbytes; - z->next_in = comp_buf; - } - z->avail_out = n; - z->next_out = uncomp_buf; - err = inflate(z, Z_FULL_FLUSH); - if ( err == Z_STREAM_END ) { - return MATIO_E_NO_ERROR; - } else if ( err != Z_OK ) { - Mat_Critical("InflateSkip: inflate returned %s", - zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err)); - return MATIO_E_FILE_FORMAT_VIOLATION; - } else { - err = MATIO_E_NO_ERROR; - } - if ( !z->avail_out ) { - cnt += n; - n = nBytes - cnt; - if ( n > READ_BLOCK_SIZE ) { - n = READ_BLOCK_SIZE; - } - z->avail_out = n; - z->next_out = uncomp_buf; - } - while ( cnt < nBytes ) { - if ( !z->avail_in ) { - size_t nbytes = fread(comp_buf, 1, n, (FILE *)mat->fp); - if ( 0 == nbytes ) { - break; - } - if ( NULL != bytesread ) { - *bytesread += nbytes; - } - z->avail_in = (uInt)nbytes; - z->next_in = comp_buf; - } - err = inflate(z, Z_FULL_FLUSH); - if ( err == Z_STREAM_END ) { - err = MATIO_E_NO_ERROR; - break; - } else if ( err != Z_OK ) { - const char *errMsg = zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err); - err = MATIO_E_FILE_FORMAT_VIOLATION; - Mat_Critical("InflateSkip: inflate returned %s", errMsg); - break; - } else { - err = MATIO_E_NO_ERROR; - } - if ( !z->avail_out ) { - cnt += n; - n = nBytes - cnt; - if ( n > READ_BLOCK_SIZE ) { - n = READ_BLOCK_SIZE; - } - z->avail_out = n; - z->next_out = uncomp_buf; - } - } - - if ( z->avail_in ) { - const long offset = -(long)z->avail_in; - (void)fseek((FILE *)mat->fp, offset, SEEK_CUR); - if ( NULL != bytesread ) { - *bytesread -= z->avail_in; - } - z->avail_in = 0; - } - - return err; -} - -/** @brief Inflate the data until @c len elements of compressed data with data - * type @c data_type has been inflated - * - * @ingroup mat_internal - * @param mat Pointer to the MAT file - * @param z zlib compression stream - * @param data_type Data type (matio_types enumerations) - * @param len Number of elements of datatype @c data_type to skip - * @param[out] bytesread Number of bytes read from the file - * @retval 0 on success - - */ -static int -InflateSkipData(mat_t *mat, z_streamp z, enum matio_types data_type, int len) -{ - if ( mat == NULL || z == NULL || len < 1 ) - return MATIO_E_BAD_ARGUMENT; - - switch ( data_type ) { - case MAT_T_UTF8: - case MAT_T_UTF16: - case MAT_T_UTF32: - return MATIO_E_OPERATION_NOT_SUPPORTED; - default: - break; - } - - return InflateSkip(mat, z, (unsigned int)Mat_SizeOf(data_type) * len, NULL); -} - -/** @brief Inflates the dimensions tag and the dimensions data - * - * @c buf must hold at least (8+4*rank) bytes where rank is the number of - * dimensions. If the end of the dimensions data is not aligned on an 8-byte - * boundary, this function eats up those bytes and stores then in @c buf. - * @ingroup mat_internal - * @param mat Pointer to the MAT file - * @param z zlib compression stream - * @param buf Pointer to store the dimensions flag and data - * @param nBytes Size of buf in bytes - * @param dims Output buffer to be allocated if (8+4*rank) > nBytes - * @param[out] bytesread Number of bytes read from the file - * @retval 0 on success - - */ -static int -InflateRankDims(mat_t *mat, z_streamp z, void *buf, size_t nBytes, mat_uint32_t **dims, - size_t *bytesread) -{ - mat_int32_t tag[2]; - int rank, i, err; - - if ( buf == NULL ) - return MATIO_E_BAD_ARGUMENT; - - err = Inflate(mat, z, buf, 8, bytesread); - if ( err ) { - return err; - } - tag[0] = *(int *)buf; - tag[1] = *((int *)buf + 1); - if ( mat->byteswap ) { - Mat_int32Swap(tag); - Mat_int32Swap(tag + 1); - } - if ( (tag[0] & 0x0000ffff) != MAT_T_INT32 ) { - Mat_Critical("InflateRankDims: Reading dimensions expected type MAT_T_INT32"); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - rank = tag[1]; - if ( rank % 8 != 0 ) - i = 8 - (rank % 8); - else - i = 0; - rank += i; - - if ( sizeof(mat_uint32_t) * (rank + 2) <= nBytes ) { - err = Inflate(mat, z, (mat_int32_t *)buf + 2, (unsigned int)rank, bytesread); - } else { - /* Cannot use too small buf, but can allocate output buffer dims */ - *dims = (mat_uint32_t *)calloc(rank, sizeof(mat_uint32_t)); - if ( NULL != *dims ) { - err = Inflate(mat, z, *dims, (unsigned int)rank, bytesread); - } else { - *((mat_int32_t *)buf + 1) = 0; - Mat_Critical("Error allocating memory for dims"); - return MATIO_E_OUT_OF_MEMORY; - } - } - - return err; -} - -/** @brief Inflates the data - * - * buf must hold at least @c nBytes bytes - * @ingroup mat_internal - * @param mat Pointer to the MAT file - * @param z zlib compression stream - * @param buf Pointer to store the uncompressed data - * @param nBytes Number of uncompressed bytes to inflate - * @param[out] bytesread Number of bytes read from the file - * @retval 0 on success - - */ -static int -Inflate(mat_t *mat, z_streamp z, void *buf, unsigned int nBytes, size_t *bytesread) -{ - mat_uint8_t comp_buf[4]; - int err = MATIO_E_NO_ERROR; - - if ( buf == NULL ) - return MATIO_E_BAD_ARGUMENT; - - if ( !z->avail_in ) { - size_t nbytes = fread(comp_buf, 1, 1, (FILE *)mat->fp); - if ( 0 == nbytes ) { - return err; - } - if ( NULL != bytesread ) { - *bytesread += nbytes; - } - z->avail_in = (uInt)nbytes; - z->next_in = comp_buf; - } - z->avail_out = nBytes; - z->next_out = ZLIB_BYTE_PTR(buf); - err = inflate(z, Z_NO_FLUSH); - if ( err != Z_OK ) { - Mat_Critical("Inflate: inflate returned %s", - zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err)); - return MATIO_E_FILE_FORMAT_VIOLATION; - } else { - err = MATIO_E_NO_ERROR; - } - while ( z->avail_out && !z->avail_in ) { - size_t nbytes = fread(comp_buf, 1, 1, (FILE *)mat->fp); - if ( 0 == nbytes ) { - break; - } - if ( NULL != bytesread ) { - *bytesread += nbytes; - } - z->avail_in = (uInt)nbytes; - z->next_in = comp_buf; - err = inflate(z, Z_NO_FLUSH); - if ( err != Z_OK ) { - Mat_Critical("Inflate: inflate returned %s", - zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err)); - return MATIO_E_FILE_FORMAT_VIOLATION; - } else { - err = MATIO_E_NO_ERROR; - } - } - - if ( z->avail_in ) { - const long offset = -(long)z->avail_in; - (void)fseek((FILE *)mat->fp, offset, SEEK_CUR); - if ( NULL != bytesread ) { - *bytesread -= z->avail_in; - } - z->avail_in = 0; - } - - if ( z->avail_out && feof((FILE *)mat->fp) ) { - Mat_Warning( - "Unexpected end-of-file: " - "Processed %u bytes, expected %u bytes", - nBytes - z->avail_out, nBytes); - memset(buf, 0, nBytes); - } - - return err; -} - -/** @brief Inflates the data in blocks - * - * buf must hold at least @c nBytes bytes - * @ingroup mat_internal - * @param mat Pointer to the MAT file - * @param z zlib compression stream - * @param buf Pointer to store the uncompressed data - * @param nBytes Number of uncompressed bytes to inflate - * @param[out] bytesread Number of bytes read from the file - * @retval 0 on success - - */ -static int -InflateData(mat_t *mat, z_streamp z, void *buf, unsigned int nBytes) -{ - mat_uint8_t comp_buf[READ_BLOCK_SIZE]; - int err = MATIO_E_NO_ERROR; - unsigned int n; - size_t bytesread = 0; - - if ( buf == NULL ) - return MATIO_E_BAD_ARGUMENT; - if ( nBytes == 0 ) { - return MATIO_E_NO_ERROR; - } - - n = nBytes < READ_BLOCK_SIZE ? nBytes : READ_BLOCK_SIZE; - if ( !z->avail_in ) { - size_t nbytes = fread(comp_buf, 1, n, (FILE *)mat->fp); - if ( 0 == nbytes ) { - return err; - } - bytesread += nbytes; - z->avail_in = (uInt)nbytes; - z->next_in = comp_buf; - } - z->avail_out = nBytes; - z->next_out = ZLIB_BYTE_PTR(buf); - err = inflate(z, Z_FULL_FLUSH); - if ( err == Z_STREAM_END ) { - return MATIO_E_NO_ERROR; - } else if ( err != Z_OK ) { - Mat_Critical("InflateData: inflate returned %s", - zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err)); - return MATIO_E_FAIL_TO_IDENTIFY; - } else { - err = MATIO_E_NO_ERROR; - } - while ( z->avail_out && !z->avail_in ) { - size_t nbytes; - if ( nBytes > READ_BLOCK_SIZE + bytesread ) { - nbytes = fread(comp_buf, 1, READ_BLOCK_SIZE, (FILE *)mat->fp); - } else if ( nBytes < 1 + bytesread ) { /* Read a byte at a time */ - nbytes = fread(comp_buf, 1, 1, (FILE *)mat->fp); - } else { - nbytes = fread(comp_buf, 1, nBytes - bytesread, (FILE *)mat->fp); - } - if ( 0 == nbytes ) { - break; - } - bytesread += nbytes; - z->avail_in = (uInt)nbytes; - z->next_in = comp_buf; - err = inflate(z, Z_FULL_FLUSH); - if ( err == Z_STREAM_END ) { - err = MATIO_E_NO_ERROR; - break; - } else if ( err != Z_OK ) { - const char *errMsg = zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err); - err = MATIO_E_FAIL_TO_IDENTIFY; - Mat_Critical("InflateData: inflate returned %s", errMsg); - break; - } else { - err = MATIO_E_NO_ERROR; - } - } - - if ( z->avail_in ) { - const long offset = -(long)z->avail_in; - (void)fseek((FILE *)mat->fp, offset, SEEK_CUR); - bytesread -= z->avail_in; - z->avail_in = 0; - } - - if ( z->avail_out && feof((FILE *)mat->fp) ) { - Mat_Warning("InflateData: Read beyond EOF error: Processed %u bytes, expected %u bytes", - nBytes - z->avail_out, nBytes); - memset(buf, 0, nBytes); - } - - return err; -} - -/** @endcond */ - -#endif - -/* ------------------------------- - * ---------- io.c - * ------------------------------- - */ -/** @file io.c - * MAT File I/O Utility Functions - */ -#if defined(_WIN32) && defined(_MSC_VER) -#define WIN32_LEAN_AND_MEAN -#define NOGDI -#include -#endif - -#if !defined(HAVE_VA_COPY) && !defined(va_copy) && defined(HAVE___VA_COPY) -#define va_copy(d, s) __va_copy(d, s) -#elif !defined(HAVE_VA_COPY) && !defined(va_copy) -#define va_copy(d, s) memcpy(&(d), &(s), sizeof(va_list)) -#endif - -#if defined(_WIN32) && defined(_MSC_VER) -/** @brief Convert from narrow UTF-8 string to wide string - * - * @ingroup mat_util - * @param src narrow string - * @return Pointer to resulting wide string, or NULL if there was an error - */ -wchar_t * -utf82u(const char *src) -{ - if ( NULL != src ) { - int srcLen = (int)strlen(src); - if ( 0 != srcLen ) { - int rc = MultiByteToWideChar(CP_UTF8, 0, src, srcLen, 0, 0); - if ( 0 != rc ) { - wchar_t *w = (wchar_t *)malloc(sizeof(wchar_t) * (rc + 1)); - if ( NULL != w ) { - w[rc] = L'\0'; - rc = MultiByteToWideChar(CP_UTF8, 0, src, srcLen, w, rc); - if ( 0 != rc ) { - return w; - } else { - free(w); - } - } - } - } else { - wchar_t *w = (wchar_t *)malloc(sizeof(wchar_t)); - if ( NULL != w ) { - w[0] = L'\0'; - return w; - } - } - } - return NULL; -} -#endif - -/** @brief Logs a Critical message and aborts the program - * - * Logs an Error message and aborts - * @ingroup mat_util - * @param format format string identical to printf format - * @param ... arguments to the format string - */ -void -Mat_Critical(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - ModelicaVFormatError(format, ap); - va_end(ap); -} - -/** @brief Prints a warning message - * - * Logs a warning message then returns - * @ingroup mat_util - * @param format format string identical to printf format - * @param ... arguments to the format string - */ -void -Mat_Warning(const char *format, ...) -{ - va_list ap; - va_start(ap, format); - ModelicaVFormatWarning(format, ap); - va_end(ap); -} - -/** @brief Calculate the size of MAT data types - * - * @ingroup mat_util - * @param data_type Data type enumeration - * @return size of the data type in bytes - */ -size_t -Mat_SizeOf(enum matio_types data_type) -{ - switch ( data_type ) { - case MAT_T_DOUBLE: - return sizeof(double); - case MAT_T_SINGLE: - return sizeof(float); -#ifdef HAVE_MATIO_INT64_T - case MAT_T_INT64: - return sizeof(mat_int64_t); -#endif -#ifdef HAVE_MATIO_UINT64_T - case MAT_T_UINT64: - return sizeof(mat_uint64_t); -#endif - case MAT_T_INT32: - return sizeof(mat_int32_t); - case MAT_T_UINT32: - return sizeof(mat_uint32_t); - case MAT_T_INT16: - return sizeof(mat_int16_t); - case MAT_T_UINT16: - return sizeof(mat_uint16_t); - case MAT_T_INT8: - return sizeof(mat_int8_t); - case MAT_T_UINT8: - return sizeof(mat_uint8_t); - case MAT_T_UTF8: - return 1; - case MAT_T_UTF16: - return 2; - case MAT_T_UTF32: - return 4; - default: - return 0; - } -} - -/* ------------------------------- - * ---------- read_data.c - * ------------------------------- - */ -/** @file read_data.c - * Matlab MAT version 5 file functions - * @ingroup MAT - */ - -/* FIXME: Implement Unicode support */ - -#define READ_DATA_NOSWAP(T) \ - do { \ - const size_t block_size = READ_BLOCK_SIZE / data_size; \ - if ( len <= block_size ) { \ - readcount = fread(v, data_size, len, (FILE *)mat->fp); \ - if ( readcount == len ) { \ - for ( i = 0; i < len; i++ ) { \ - data[i] = (T)v[i]; \ - } \ - } \ - } else { \ - size_t j; \ - int err = 0; \ - readcount = 0; \ - for ( i = 0; i < len - block_size; i += block_size ) { \ - j = fread(v, data_size, block_size, (FILE *)mat->fp); \ - readcount += j; \ - if ( j == block_size ) { \ - for ( j = 0; j < block_size; j++ ) { \ - data[i + j] = (T)v[j]; \ - } \ - } else { \ - err = 1; \ - break; \ - } \ - } \ - if ( 0 == err && len > i ) { \ - j = fread(v, data_size, len - i, (FILE *)mat->fp); \ - readcount += j; \ - if ( j == len - i ) { \ - for ( j = 0; j < len - i; j++ ) { \ - data[i + j] = (T)v[j]; \ - } \ - } \ - } \ - } \ - } while ( 0 ) - -#define READ_DATA(T, SwapFunc) \ - do { \ - if ( mat->byteswap ) { \ - const size_t block_size = READ_BLOCK_SIZE / data_size; \ - if ( len <= block_size ) { \ - readcount = fread(v, data_size, len, (FILE *)mat->fp); \ - if ( readcount == len ) { \ - for ( i = 0; i < len; i++ ) { \ - data[i] = (T)SwapFunc(&v[i]); \ - } \ - } \ - } else { \ - size_t j; \ - int err = 0; \ - readcount = 0; \ - for ( i = 0; i < len - block_size; i += block_size ) { \ - j = fread(v, data_size, block_size, (FILE *)mat->fp); \ - readcount += j; \ - if ( j == block_size ) { \ - for ( j = 0; j < block_size; j++ ) { \ - data[i + j] = (T)SwapFunc(&v[j]); \ - } \ - } else { \ - err = 1; \ - break; \ - } \ - } \ - if ( 0 == err && len > i ) { \ - j = fread(v, data_size, len - i, (FILE *)mat->fp); \ - readcount += j; \ - if ( j == len - i ) { \ - for ( j = 0; j < len - i; j++ ) { \ - data[i + j] = (T)SwapFunc(&v[j]); \ - } \ - } \ - } \ - } \ - } else { \ - READ_DATA_NOSWAP(T); \ - } \ - } while ( 0 ) - -#if HAVE_ZLIB -#define READ_COMPRESSED_DATA_NOSWAP(T) \ - do { \ - const size_t block_size = READ_BLOCK_SIZE / data_size; \ - if ( len <= block_size ) { \ - InflateData(mat, z, v, len *data_size); \ - for ( i = 0; i < len; i++ ) { \ - data[i] = (T)v[i]; \ - } \ - } else { \ - mat_uint32_t j; \ - len -= block_size; \ - for ( i = 0; i < len; i += block_size ) { \ - InflateData(mat, z, v, block_size *data_size); \ - for ( j = 0; j < block_size; j++ ) { \ - data[i + j] = (T)v[j]; \ - } \ - } \ - len -= (i - block_size); \ - InflateData(mat, z, v, len *data_size); \ - for ( j = 0; j < len; j++ ) { \ - data[i + j] = (T)v[j]; \ - } \ - } \ - } while ( 0 ) - -#define READ_COMPRESSED_DATA(T, SwapFunc) \ - do { \ - if ( mat->byteswap ) { \ - const size_t block_size = READ_BLOCK_SIZE / data_size; \ - if ( len <= block_size ) { \ - InflateData(mat, z, v, len *data_size); \ - for ( i = 0; i < len; i++ ) { \ - data[i] = (T)SwapFunc(&v[i]); \ - } \ - } else { \ - mat_uint32_t j; \ - len -= block_size; \ - for ( i = 0; i < len; i += block_size ) { \ - InflateData(mat, z, v, block_size *data_size); \ - for ( j = 0; j < block_size; j++ ) { \ - data[i + j] = (T)SwapFunc(&v[j]); \ - } \ - } \ - len -= (i - block_size); \ - InflateData(mat, z, v, len *data_size); \ - for ( j = 0; j < len; j++ ) { \ - data[i + j] = (T)SwapFunc(&v[j]); \ - } \ - } \ - } else { \ - READ_COMPRESSED_DATA_NOSWAP(T); \ - } \ - } while ( 0 ) - -#endif - -/* - * -------------------------------------------------------------------------- - * Routines to read data of any type into arrays of a specific type - * -------------------------------------------------------------------------- - */ - -/** @cond mat_devman */ - -#define READ_TYPE_DOUBLE 1 -#define READ_TYPE_SINGLE 2 -#define READ_TYPE_INT64 3 -#define READ_TYPE_UINT64 4 -#define READ_TYPE_INT32 5 -#define READ_TYPE_UINT32 6 -#define READ_TYPE_INT16 7 -#define READ_TYPE_UINT16 8 -#define READ_TYPE_INT8 9 -#define READ_TYPE_UINT8 10 - -#define READ_TYPE double -#define READ_TYPE_TYPE READ_TYPE_DOUBLE -#define READ_TYPED_FUNC1 ReadDoubleData -#define READ_TYPED_FUNC2 ReadCompressedDoubleData -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 - -#define READ_TYPE float -#define READ_TYPE_TYPE READ_TYPE_SINGLE -#define READ_TYPED_FUNC1 ReadSingleData -#define READ_TYPED_FUNC2 ReadCompressedSingleData -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 - -#ifdef HAVE_MATIO_INT64_T -#define READ_TYPE mat_int64_t -#define READ_TYPE_TYPE READ_TYPE_INT64 -#define READ_TYPED_FUNC1 ReadInt64Data -#define READ_TYPED_FUNC2 ReadCompressedInt64Data -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 -#endif /* HAVE_MATIO_INT64_T */ - -#ifdef HAVE_MATIO_UINT64_T -#define READ_TYPE mat_uint64_t -#define READ_TYPE_TYPE READ_TYPE_UINT64 -#define READ_TYPED_FUNC1 ReadUInt64Data -#define READ_TYPED_FUNC2 ReadCompressedUInt64Data -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 -#endif /* HAVE_MATIO_UINT64_T */ - -#define READ_TYPE mat_int32_t -#define READ_TYPE_TYPE READ_TYPE_INT32 -#define READ_TYPED_FUNC1 ReadInt32Data -#define READ_TYPED_FUNC2 ReadCompressedInt32Data -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 - -#define READ_TYPE mat_uint32_t -#define READ_TYPE_TYPE READ_TYPE_UINT32 -#define READ_TYPED_FUNC1 ReadUInt32Data -#define READ_TYPED_FUNC2 ReadCompressedUInt32Data -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 - -#define READ_TYPE mat_int16_t -#define READ_TYPE_TYPE READ_TYPE_INT16 -#define READ_TYPED_FUNC1 ReadInt16Data -#define READ_TYPED_FUNC2 ReadCompressedInt16Data -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 - -#define READ_TYPE mat_uint16_t -#define READ_TYPE_TYPE READ_TYPE_UINT16 -#define READ_TYPED_FUNC1 ReadUInt16Data -#define READ_TYPED_FUNC2 ReadCompressedUInt16Data -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 - -#define READ_TYPE mat_int8_t -#define READ_TYPE_TYPE READ_TYPE_INT8 -#define READ_TYPED_FUNC1 ReadInt8Data -#define READ_TYPED_FUNC2 ReadCompressedInt8Data -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 - -#define READ_TYPE mat_uint8_t -#define READ_TYPE_TYPE READ_TYPE_UINT8 -#define READ_TYPED_FUNC1 ReadUInt8Data -#define READ_TYPED_FUNC2 ReadCompressedUInt8Data -#include "read_data_impl.h" -#undef READ_TYPE -#undef READ_TYPE_TYPE -#undef READ_TYPED_FUNC1 -#undef READ_TYPED_FUNC2 - -#if HAVE_ZLIB -/** @brief Reads data of type @c data_type into a char type - * - * Reads from the MAT file @c len compressed elements of data type @c data_type - * storing them as char's in @c data. - * @ingroup mat_internal - * @param mat MAT file pointer - * @param z Pointer to the zlib stream for inflation - * @param data Pointer to store the output char values (len*sizeof(char)) - * @param data_type one of the @c matio_types enumerations which is the source - * data type in the file - * @param len Number of elements of type @c data_type to read from the file - * @retval Number of bytes read from the file - */ -static int -ReadCompressedCharData(mat_t *mat, z_streamp z, void *data, enum matio_types data_type, size_t len) -{ - size_t nBytes = 0; - int err; - - if ( mat == NULL || data == NULL || mat->fp == NULL ) - return 0; - - err = Mul(&nBytes, len, Mat_SizeOf(data_type)); - if ( err ) { - return 0; - } - - switch ( data_type ) { - case MAT_T_UINT8: - case MAT_T_UTF8: - err = InflateData(mat, z, data, (mat_uint32_t)nBytes); - break; - case MAT_T_UINT16: - case MAT_T_UTF16: - err = InflateData(mat, z, data, (mat_uint32_t)nBytes); - if ( mat->byteswap ) { - mat_uint16_t *ptr = (mat_uint16_t *)data; - size_t i; - for ( i = 0; i < len; i++ ) { - Mat_uint16Swap((mat_uint16_t *)&ptr[i]); - } - } - break; - default: - Mat_Warning( - "ReadCompressedCharData: %d is not a supported data " - "type for character data", - data_type); - break; - } - - if ( err ) { - nBytes = 0; - } - return (int)nBytes; -} -#endif - -static size_t -ReadCharData(mat_t *mat, void *_data, enum matio_types data_type, size_t len) -{ - size_t nBytes = 0; - int err = 0; - size_t data_size; - - if ( mat == NULL || _data == NULL || mat->fp == NULL ) - return 0; - - data_size = Mat_SizeOf(data_type); - - switch ( data_type ) { - case MAT_T_UINT8: - case MAT_T_UTF8: { - err = Read(_data, data_size, len, (FILE *)mat->fp, &nBytes); - break; - } - case MAT_T_UINT16: - case MAT_T_UTF16: { - size_t i, readcount; - mat_uint16_t *data = (mat_uint16_t *)_data; - mat_uint16_t v[READ_BLOCK_SIZE / sizeof(mat_uint16_t)]; - READ_DATA(mat_uint16_t, Mat_uint16Swap); - err = Mul(&nBytes, readcount, data_size); - break; - } - default: - Mat_Warning( - "ReadCharData: %d is not a supported data type for " - "character data", - data_type); - break; - } - if ( err ) { - nBytes = 0; - } - return nBytes; -} - -#undef READ_DATA -#undef READ_DATA_NOSWAP - -/* - *------------------------------------------------------------------- - * Routines to read "slabs" of data - *------------------------------------------------------------------- - */ - -#define READ_DATA_SLABN_RANK_LOOP \ - do { \ - for ( j = 1; j < rank; j++ ) { \ - cnt[j]++; \ - if ( (cnt[j] % edge[j]) == 0 ) { \ - cnt[j] = 0; \ - if ( (I % dimp[j]) != 0 ) { \ - (void)fseek((FILE *)mat->fp, \ - data_size *(dimp[j] - (I % dimp[j]) + dimp[j - 1] * start[j]), \ - SEEK_CUR); \ - I += dimp[j] - (I % dimp[j]) + (ptrdiff_t)dimp[j - 1] * start[j]; \ - } else if ( start[j] ) { \ - (void)fseek((FILE *)mat->fp, data_size *(dimp[j - 1] * start[j]), SEEK_CUR); \ - I += (ptrdiff_t)dimp[j - 1] * start[j]; \ - } \ - } else { \ - I += inc[j]; \ - (void)fseek((FILE *)mat->fp, data_size *inc[j], SEEK_CUR); \ - break; \ - } \ - } \ - } while ( 0 ) - -#define READ_DATA_SLABN(ReadDataFunc) \ - do { \ - inc[0] = stride[0] - 1; \ - dimp[0] = dims[0]; \ - N = edge[0]; \ - I = 0; /* start[0]; */ \ - for ( i = 1; i < rank; i++ ) { \ - inc[i] = stride[i] - 1; \ - dimp[i] = dims[i - 1]; \ - for ( j = i; j--; ) { \ - inc[i] *= dims[j]; \ - dimp[i] *= dims[j + 1]; \ - } \ - N *= edge[i]; \ - I += (ptrdiff_t)dimp[i - 1] * start[i]; \ - } \ - (void)fseek((FILE *)mat->fp, I *data_size, SEEK_CUR); \ - if ( stride[0] == 1 ) { \ - for ( i = 0; i < N; i += edge[0] ) { \ - if ( start[0] ) { \ - (void)fseek((FILE *)mat->fp, start[0] * data_size, SEEK_CUR); \ - I += start[0]; \ - } \ - ReadDataFunc(mat, ptr + i, data_type, edge[0]); \ - I += dims[0] - start[0]; \ - (void)fseek((FILE *)mat->fp, data_size *(dims[0] - edge[0] - start[0]), SEEK_CUR); \ - READ_DATA_SLABN_RANK_LOOP; \ - } \ - } else { \ - for ( i = 0; i < N; i += edge[0] ) { \ - if ( start[0] ) { \ - (void)fseek((FILE *)mat->fp, start[0] * data_size, SEEK_CUR); \ - I += start[0]; \ - } \ - for ( j = 0; j < edge[0]; j++ ) { \ - ReadDataFunc(mat, ptr + i + j, data_type, 1); \ - (void)fseek((FILE *)mat->fp, data_size *(stride[0] - 1), SEEK_CUR); \ - I += stride[0]; \ - } \ - I += dims[0] - (ptrdiff_t)edge[0] * stride[0] - start[0]; \ - (void)fseek((FILE *)mat->fp, \ - data_size *(dims[0] - (ptrdiff_t)edge[0] * stride[0] - start[0]), \ - SEEK_CUR); \ - READ_DATA_SLABN_RANK_LOOP; \ - } \ - } \ - } while ( 0 ) - -/** @brief Reads data of type @c data_type by user-defined dimensions - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param data Pointer to store the output data - * @param class_type Type of data class (matio_classes enumerations) - * @param data_type Datatype of the stored data (matio_types enumerations) - * @param rank Number of dimensions in the data - * @param dims Dimensions of the data - * @param start Index to start reading data in each dimension - * @param stride Read every @c stride elements in each dimension - * @param edge Number of elements to read in each dimension - * @retval Number of bytes read from the file, or -1 on error - */ -static int -ReadDataSlabN(mat_t *mat, void *data, enum matio_classes class_type, enum matio_types data_type, - int rank, size_t *dims, int *start, int *stride, int *edge) -{ - int nBytes = 0, i, j, N, I = 0; - int inc[10] = - { - 0, - }, - cnt[10] = - { - 0, - }, - dimp[10] = { - 0, - }; - size_t data_size; - - if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) || (start == NULL) || - (stride == NULL) || (edge == NULL) ) { - return -1; - } else if ( rank > 10 ) { - return -1; - } - - data_size = Mat_SizeOf(data_type); - - switch ( class_type ) { - case MAT_C_DOUBLE: { - double *ptr = (double *)data; - READ_DATA_SLABN(ReadDoubleData); - break; - } - case MAT_C_SINGLE: { - float *ptr = (float *)data; - READ_DATA_SLABN(ReadSingleData); - break; - } -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: { - mat_int64_t *ptr = (mat_int64_t *)data; - READ_DATA_SLABN(ReadInt64Data); - break; - } -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: { - mat_uint64_t *ptr = (mat_uint64_t *)data; - READ_DATA_SLABN(ReadUInt64Data); - break; - } -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_C_INT32: { - mat_int32_t *ptr = (mat_int32_t *)data; - READ_DATA_SLABN(ReadInt32Data); - break; - } - case MAT_C_UINT32: { - mat_uint32_t *ptr = (mat_uint32_t *)data; - READ_DATA_SLABN(ReadUInt32Data); - break; - } - case MAT_C_INT16: { - mat_int16_t *ptr = (mat_int16_t *)data; - READ_DATA_SLABN(ReadInt16Data); - break; - } - case MAT_C_UINT16: { - mat_uint16_t *ptr = (mat_uint16_t *)data; - READ_DATA_SLABN(ReadUInt16Data); - break; - } - case MAT_C_INT8: { - mat_int8_t *ptr = (mat_int8_t *)data; - READ_DATA_SLABN(ReadInt8Data); - break; - } - case MAT_C_UINT8: { - mat_uint8_t *ptr = (mat_uint8_t *)data; - READ_DATA_SLABN(ReadUInt8Data); - break; - } - default: - nBytes = 0; - } - return nBytes; -} - -#undef READ_DATA_SLABN -#undef READ_DATA_SLABN_RANK_LOOP - -#if HAVE_ZLIB -#define READ_COMPRESSED_DATA_SLABN_RANK_LOOP \ - do { \ - for ( j = 1; j < rank; j++ ) { \ - cnt[j]++; \ - if ( (cnt[j] % edge[j]) == 0 ) { \ - cnt[j] = 0; \ - if ( (I % dimp[j]) != 0 ) { \ - InflateSkipData(mat, &z_copy, data_type, \ - dimp[j] - (I % dimp[j]) + dimp[j - 1] * start[j]); \ - I += dimp[j] - (I % dimp[j]) + (ptrdiff_t)dimp[j - 1] * start[j]; \ - } else if ( start[j] ) { \ - InflateSkipData(mat, &z_copy, data_type, dimp[j - 1] * start[j]); \ - I += (ptrdiff_t)dimp[j - 1] * start[j]; \ - } \ - } else { \ - if ( inc[j] ) { \ - I += inc[j]; \ - InflateSkipData(mat, &z_copy, data_type, inc[j]); \ - } \ - break; \ - } \ - } \ - } while ( 0 ) - -#define READ_COMPRESSED_DATA_SLABN(ReadDataFunc) \ - do { \ - inc[0] = stride[0] - 1; \ - dimp[0] = dims[0]; \ - N = edge[0]; \ - I = 0; \ - for ( i = 1; i < rank; i++ ) { \ - inc[i] = stride[i] - 1; \ - dimp[i] = dims[i - 1]; \ - for ( j = i; j--; ) { \ - inc[i] *= dims[j]; \ - dimp[i] *= dims[j + 1]; \ - } \ - N *= edge[i]; \ - I += (ptrdiff_t)dimp[i - 1] * start[i]; \ - } \ - /* Skip all data to the starting indices */ \ - InflateSkipData(mat, &z_copy, data_type, I); \ - if ( stride[0] == 1 ) { \ - for ( i = 0; i < N; i += edge[0] ) { \ - if ( start[0] ) { \ - InflateSkipData(mat, &z_copy, data_type, start[0]); \ - I += start[0]; \ - } \ - ReadDataFunc(mat, &z_copy, ptr + i, data_type, edge[0]); \ - InflateSkipData(mat, &z_copy, data_type, dims[0] - start[0] - edge[0]); \ - I += dims[0] - start[0]; \ - READ_COMPRESSED_DATA_SLABN_RANK_LOOP; \ - } \ - } else { \ - for ( i = 0; i < N; i += edge[0] ) { \ - if ( start[0] ) { \ - InflateSkipData(mat, &z_copy, data_type, start[0]); \ - I += start[0]; \ - } \ - for ( j = 0; j < edge[0] - 1; j++ ) { \ - ReadDataFunc(mat, &z_copy, ptr + i + j, data_type, 1); \ - InflateSkipData(mat, &z_copy, data_type, (stride[0] - 1)); \ - I += stride[0]; \ - } \ - ReadDataFunc(mat, &z_copy, ptr + i + j, data_type, 1); \ - I += dims[0] - (ptrdiff_t)(edge[0] - 1) * stride[0] - start[0]; \ - InflateSkipData(mat, &z_copy, data_type, \ - dims[0] - (ptrdiff_t)(edge[0] - 1) * stride[0] - start[0] - 1); \ - READ_COMPRESSED_DATA_SLABN_RANK_LOOP; \ - } \ - } \ - } while ( 0 ) - -/** @brief Reads data of type @c data_type by user-defined dimensions - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param z zlib compression stream - * @param data Pointer to store the output data - * @param class_type Type of data class (matio_classes enumerations) - * @param data_type Datatype of the stored data (matio_types enumerations) - * @param rank Number of dimensions in the data - * @param dims Dimensions of the data - * @param start Index to start reading data in each dimension - * @param stride Read every @c stride elements in each dimension - * @param edge Number of elements to read in each dimension - * @retval Number of bytes read from the file, or -1 on error - */ -static int -ReadCompressedDataSlabN(mat_t *mat, z_streamp z, void *data, enum matio_classes class_type, - enum matio_types data_type, int rank, size_t *dims, int *start, int *stride, - int *edge) -{ - int nBytes = 0, i, j, N, I = 0, err; - int inc[10] = - { - 0, - }, - cnt[10] = - { - 0, - }, - dimp[10] = { - 0, - }; - z_stream z_copy = { - 0, - }; - - if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) || (start == NULL) || - (stride == NULL) || (edge == NULL) ) { - return 0; - } else if ( rank > 10 ) { - return 0; - } - - err = inflateCopy(&z_copy, z); - if ( err != Z_OK ) { - Mat_Critical("inflateCopy returned error %s", zError(err)); - return -1; - } - switch ( class_type ) { - case MAT_C_DOUBLE: { - double *ptr = (double *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedDoubleData); - break; - } - case MAT_C_SINGLE: { - float *ptr = (float *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedSingleData); - break; - } -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: { - mat_int64_t *ptr = (mat_int64_t *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedInt64Data); - break; - } -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: { - mat_uint64_t *ptr = (mat_uint64_t *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedUInt64Data); - break; - } -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_C_INT32: { - mat_int32_t *ptr = (mat_int32_t *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedInt32Data); - break; - } - case MAT_C_UINT32: { - mat_uint32_t *ptr = (mat_uint32_t *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedUInt32Data); - break; - } - case MAT_C_INT16: { - mat_int16_t *ptr = (mat_int16_t *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedInt16Data); - break; - } - case MAT_C_UINT16: { - mat_uint16_t *ptr = (mat_uint16_t *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedUInt16Data); - break; - } - case MAT_C_INT8: { - mat_int8_t *ptr = (mat_int8_t *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedInt8Data); - break; - } - case MAT_C_UINT8: { - mat_uint8_t *ptr = (mat_uint8_t *)data; - READ_COMPRESSED_DATA_SLABN(ReadCompressedUInt8Data); - break; - } - default: - nBytes = 0; - } - inflateEnd(&z_copy); - return nBytes; -} - -#undef READ_COMPRESSED_DATA_SLABN -#undef READ_COMPRESSED_DATA_SLABN_RANK_LOOP -#endif - -#define READ_DATA_SLAB1(ReadDataFunc) \ - do { \ - if ( !stride ) { \ - bytesread += ReadDataFunc(mat, ptr, data_type, edge); \ - } else { \ - for ( i = 0; i < edge; i++ ) { \ - bytesread += ReadDataFunc(mat, ptr + i, data_type, 1); \ - (void)fseek((FILE *)mat->fp, stride, SEEK_CUR); \ - } \ - } \ - } while ( 0 ) - -/** @brief Reads data of type @c data_type by user-defined dimensions for 1-D - * data - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param data Pointer to store the output data - * @param class_type Type of data class (matio_classes enumerations) - * @param data_type Datatype of the stored data (matio_types enumerations) - * @param start Index to start reading data - * @param stride Read every @c stride elements - * @param edge Number of elements to read - * @return Number of bytes read from the file, or -1 on error - */ -static int -ReadDataSlab1(mat_t *mat, void *data, enum matio_classes class_type, enum matio_types data_type, - int start, int stride, int edge) -{ - int i; - size_t data_size; - int bytesread = 0; - - data_size = Mat_SizeOf(data_type); - (void)fseek((FILE *)mat->fp, start * data_size, SEEK_CUR); - stride = data_size * (stride - 1); - - switch ( class_type ) { - case MAT_C_DOUBLE: { - double *ptr = (double *)data; - READ_DATA_SLAB1(ReadDoubleData); - break; - } - case MAT_C_SINGLE: { - float *ptr = (float *)data; - READ_DATA_SLAB1(ReadSingleData); - break; - } -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: { - mat_int64_t *ptr = (mat_int64_t *)data; - READ_DATA_SLAB1(ReadInt64Data); - break; - } -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: { - mat_uint64_t *ptr = (mat_uint64_t *)data; - READ_DATA_SLAB1(ReadUInt64Data); - break; - } -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_C_INT32: { - mat_int32_t *ptr = (mat_int32_t *)data; - READ_DATA_SLAB1(ReadInt32Data); - break; - } - case MAT_C_UINT32: { - mat_uint32_t *ptr = (mat_uint32_t *)data; - READ_DATA_SLAB1(ReadUInt32Data); - break; - } - case MAT_C_INT16: { - mat_int16_t *ptr = (mat_int16_t *)data; - READ_DATA_SLAB1(ReadInt16Data); - break; - } - case MAT_C_UINT16: { - mat_uint16_t *ptr = (mat_uint16_t *)data; - READ_DATA_SLAB1(ReadUInt16Data); - break; - } - case MAT_C_INT8: { - mat_int8_t *ptr = (mat_int8_t *)data; - READ_DATA_SLAB1(ReadInt8Data); - break; - } - case MAT_C_UINT8: { - mat_uint8_t *ptr = (mat_uint8_t *)data; - READ_DATA_SLAB1(ReadUInt8Data); - break; - } - default: - return 0; - } - - return bytesread; -} - -#undef READ_DATA_SLAB1 - -#define READ_DATA_SLAB2(ReadDataFunc) \ - do { \ - /* If stride[0] is 1 and stride[1] is 1, we are reading all of the */ \ - /* data so get rid of the loops. */ \ - if ( (stride[0] == 1 && (size_t)edge[0] == dims[0]) && (stride[1] == 1) ) { \ - ReadDataFunc(mat, ptr, data_type, (ptrdiff_t)edge[0] * edge[1]); \ - } else { \ - row_stride = (long)(stride[0] - 1) * data_size; \ - col_stride = (long)stride[1] * dims[0] * data_size; \ - pos = ftell((FILE *)mat->fp); \ - if ( pos == -1L ) { \ - Mat_Critical("Couldn't determine file position"); \ - return -1; \ - } \ - (void)fseek((FILE *)mat->fp, (long)start[1] * dims[0] * data_size, SEEK_CUR); \ - for ( i = 0; i < edge[1]; i++ ) { \ - pos = ftell((FILE *)mat->fp); \ - if ( pos == -1L ) { \ - Mat_Critical("Couldn't determine file position"); \ - return -1; \ - } \ - (void)fseek((FILE *)mat->fp, (long)start[0] * data_size, SEEK_CUR); \ - for ( j = 0; j < edge[0]; j++ ) { \ - ReadDataFunc(mat, ptr++, data_type, 1); \ - (void)fseek((FILE *)mat->fp, row_stride, SEEK_CUR); \ - } \ - pos2 = ftell((FILE *)mat->fp); \ - if ( pos2 == -1L ) { \ - Mat_Critical("Couldn't determine file position"); \ - return -1; \ - } \ - pos += col_stride - pos2; \ - (void)fseek((FILE *)mat->fp, pos, SEEK_CUR); \ - } \ - } \ - } while ( 0 ) - -/** @brief Reads data of type @c data_type by user-defined dimensions for 2-D - * data - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param data Pointer to store the output data - * @param class_type Type of data class (matio_classes enumerations) - * @param data_type Datatype of the stored data (matio_types enumerations) - * @param dims Dimensions of the data - * @param start Index to start reading data in each dimension - * @param stride Read every @c stride elements in each dimension - * @param edge Number of elements to read in each dimension - * @retval Number of bytes read from the file, or -1 on error - */ -static int -ReadDataSlab2(mat_t *mat, void *data, enum matio_classes class_type, enum matio_types data_type, - size_t *dims, int *start, int *stride, int *edge) -{ - int nBytes = 0, data_size, i, j; - long pos, row_stride, col_stride, pos2; - - if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) || (start == NULL) || - (stride == NULL) || (edge == NULL) ) { - return 0; - } - - data_size = Mat_SizeOf(data_type); - - switch ( class_type ) { - case MAT_C_DOUBLE: { - double *ptr = (double *)data; - READ_DATA_SLAB2(ReadDoubleData); - break; - } - case MAT_C_SINGLE: { - float *ptr = (float *)data; - READ_DATA_SLAB2(ReadSingleData); - break; - } -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: { - mat_int64_t *ptr = (mat_int64_t *)data; - READ_DATA_SLAB2(ReadInt64Data); - break; - } -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: { - mat_uint64_t *ptr = (mat_uint64_t *)data; - READ_DATA_SLAB2(ReadUInt64Data); - break; - } -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_C_INT32: { - mat_int32_t *ptr = (mat_int32_t *)data; - READ_DATA_SLAB2(ReadInt32Data); - break; - } - case MAT_C_UINT32: { - mat_uint32_t *ptr = (mat_uint32_t *)data; - READ_DATA_SLAB2(ReadUInt32Data); - break; - } - case MAT_C_INT16: { - mat_int16_t *ptr = (mat_int16_t *)data; - READ_DATA_SLAB2(ReadInt16Data); - break; - } - case MAT_C_UINT16: { - mat_uint16_t *ptr = (mat_uint16_t *)data; - READ_DATA_SLAB2(ReadUInt16Data); - break; - } - case MAT_C_INT8: { - mat_int8_t *ptr = (mat_int8_t *)data; - READ_DATA_SLAB2(ReadInt8Data); - break; - } - case MAT_C_UINT8: { - mat_uint8_t *ptr = (mat_uint8_t *)data; - READ_DATA_SLAB2(ReadUInt8Data); - break; - } - default: - nBytes = 0; - } - return nBytes; -} - -#undef READ_DATA_SLAB2 - -#if HAVE_ZLIB -#define READ_COMPRESSED_DATA_SLAB1(ReadDataFunc) \ - do { \ - if ( !stride ) { \ - nBytes += ReadDataFunc(mat, &z_copy, ptr, data_type, edge); \ - } else { \ - for ( i = 0; i < edge; i++ ) { \ - nBytes += ReadDataFunc(mat, &z_copy, ptr + i, data_type, 1); \ - InflateSkipData(mat, &z_copy, data_type, stride); \ - } \ - } \ - } while ( 0 ) - -/** @brief Reads data of type @c data_type by user-defined dimensions for 1-D - * data - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param z zlib compression stream - * @param data Pointer to store the output data - * @param class_type Type of data class (matio_classes enumerations) - * @param data_type Datatype of the stored data (matio_types enumerations) - * @param dims Dimensions of the data - * @param start Index to start reading data in each dimension - * @param stride Read every @c stride elements in each dimension - * @param edge Number of elements to read in each dimension - * @retval Number of bytes read from the file, or -1 on error - */ -static int -ReadCompressedDataSlab1(mat_t *mat, z_streamp z, void *data, enum matio_classes class_type, - enum matio_types data_type, int start, int stride, int edge) -{ - int nBytes = 0, i, err; - z_stream z_copy = { - 0, - }; - - if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) ) - return 0; - - stride--; - err = inflateCopy(&z_copy, z); - if ( err != Z_OK ) { - Mat_Critical("inflateCopy returned error %s", zError(err)); - return -1; - } - InflateSkipData(mat, &z_copy, data_type, start); - switch ( class_type ) { - case MAT_C_DOUBLE: { - double *ptr = (double *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedDoubleData); - break; - } - case MAT_C_SINGLE: { - float *ptr = (float *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedSingleData); - break; - } -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: { - mat_int64_t *ptr = (mat_int64_t *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedInt64Data); - break; - } -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: { - mat_uint64_t *ptr = (mat_uint64_t *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedUInt64Data); - break; - } -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_C_INT32: { - mat_int32_t *ptr = (mat_int32_t *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedInt32Data); - break; - } - case MAT_C_UINT32: { - mat_uint32_t *ptr = (mat_uint32_t *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedUInt32Data); - break; - } - case MAT_C_INT16: { - mat_int16_t *ptr = (mat_int16_t *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedInt16Data); - break; - } - case MAT_C_UINT16: { - mat_uint16_t *ptr = (mat_uint16_t *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedUInt16Data); - break; - } - case MAT_C_INT8: { - mat_int8_t *ptr = (mat_int8_t *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedInt8Data); - break; - } - case MAT_C_UINT8: { - mat_uint8_t *ptr = (mat_uint8_t *)data; - READ_COMPRESSED_DATA_SLAB1(ReadCompressedUInt8Data); - break; - } - default: - break; - } - inflateEnd(&z_copy); - return nBytes; -} - -#undef READ_COMPRESSED_DATA_SLAB1 - -#define READ_COMPRESSED_DATA_SLAB2(ReadDataFunc) \ - do { \ - row_stride = (stride[0] - 1); \ - col_stride = (stride[1] - 1) * dims[0]; \ - InflateSkipData(mat, &z_copy, data_type, start[1] * dims[0]); \ - /* If stride[0] is 1 and stride[1] is 1, we are reading all of the */ \ - /* data so get rid of the loops. If stride[0] is 1 and stride[1] */ \ - /* is not 0, we are reading whole columns, so get rid of inner loop */ \ - /* to speed up the code */ \ - if ( (stride[0] == 1 && (size_t)edge[0] == dims[0]) && (stride[1] == 1) ) { \ - ReadDataFunc(mat, &z_copy, ptr, data_type, (ptrdiff_t)edge[0] * edge[1]); \ - } else if ( stride[0] == 1 ) { \ - for ( i = 0; i < edge[1]; i++ ) { \ - InflateSkipData(mat, &z_copy, data_type, start[0]); \ - ReadDataFunc(mat, &z_copy, ptr, data_type, edge[0]); \ - ptr += edge[0]; \ - pos = dims[0] - (ptrdiff_t)(edge[0] - 1) * stride[0] - 1 - start[0] + col_stride; \ - InflateSkipData(mat, &z_copy, data_type, pos); \ - } \ - } else { \ - for ( i = 0; i < edge[1]; i++ ) { \ - InflateSkipData(mat, &z_copy, data_type, start[0]); \ - for ( j = 0; j < edge[0] - 1; j++ ) { \ - ReadDataFunc(mat, &z_copy, ptr++, data_type, 1); \ - InflateSkipData(mat, &z_copy, data_type, row_stride); \ - } \ - ReadDataFunc(mat, &z_copy, ptr++, data_type, 1); \ - pos = dims[0] - (ptrdiff_t)(edge[0] - 1) * stride[0] - 1 - start[0] + col_stride; \ - InflateSkipData(mat, &z_copy, data_type, pos); \ - } \ - } \ - } while ( 0 ) - -/** @brief Reads data of type @c data_type by user-defined dimensions for 2-D - * data - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param z zlib compression stream - * @param data Pointer to store the output data - * @param class_type Type of data class (matio_classes enumerations) - * @param data_type Datatype of the stored data (matio_types enumerations) - * @param dims Dimensions of the data - * @param start Index to start reading data in each dimension - * @param stride Read every @c stride elements in each dimension - * @param edge Number of elements to read in each dimension - * @retval Number of bytes read from the file, or -1 on error - */ -static int -ReadCompressedDataSlab2(mat_t *mat, z_streamp z, void *data, enum matio_classes class_type, - enum matio_types data_type, size_t *dims, int *start, int *stride, - int *edge) -{ - int nBytes = 0, i, j, err; - int pos, row_stride, col_stride; - z_stream z_copy = { - 0, - }; - - if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) || (start == NULL) || - (stride == NULL) || (edge == NULL) ) { - return 0; - } - - err = inflateCopy(&z_copy, z); - if ( err != Z_OK ) { - Mat_Critical("inflateCopy returned error %s", zError(err)); - return -1; - } - switch ( class_type ) { - case MAT_C_DOUBLE: { - double *ptr = (double *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedDoubleData); - break; - } - case MAT_C_SINGLE: { - float *ptr = (float *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedSingleData); - break; - } -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: { - mat_int64_t *ptr = (mat_int64_t *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedInt64Data); - break; - } -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: { - mat_uint64_t *ptr = (mat_uint64_t *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedUInt64Data); - break; - } -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_C_INT32: { - mat_int32_t *ptr = (mat_int32_t *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedInt32Data); - break; - } - case MAT_C_UINT32: { - mat_uint32_t *ptr = (mat_uint32_t *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedUInt32Data); - break; - } - case MAT_C_INT16: { - mat_int16_t *ptr = (mat_int16_t *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedInt16Data); - break; - } - case MAT_C_UINT16: { - mat_uint16_t *ptr = (mat_uint16_t *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedUInt16Data); - break; - } - case MAT_C_INT8: { - mat_int8_t *ptr = (mat_int8_t *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedInt8Data); - break; - } - case MAT_C_UINT8: { - mat_uint8_t *ptr = (mat_uint8_t *)data; - READ_COMPRESSED_DATA_SLAB2(ReadCompressedUInt8Data); - break; - } - default: - nBytes = 0; - } - inflateEnd(&z_copy); - return nBytes; -} - -#undef READ_COMPRESSED_DATA_SLAB2 -#endif - -/** @endcond */ - -/* ------------------------------- - * ---------- mat.c - * ------------------------------- - */ -/** @file mat.c - * Matlab MAT file functions - * @ingroup MAT - */ - -/* FIXME: Implement Unicode support */ - -#ifndef MAT5_H -#define MAT5_H - -static mat_t *Mat_Create5(const char *matname, const char *hdr_str); - -static matvar_t *Mat_VarReadNextInfo5(mat_t *mat); -static int Mat_VarRead5(mat_t *mat, matvar_t *matvar); -static int Mat_VarReadData5(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, - int *edge); -static int Mat_VarReadDataLinear5(mat_t *mat, matvar_t *matvar, void *data, int start, int stride, - int edge); -static int Mat_VarWrite5(mat_t *mat, matvar_t *matvar, int compress); - -#endif - -#ifndef MAT4_H -#define MAT4_H - -static mat_t *Mat_Create4(const char *matname); - -static int Mat_VarWrite4(mat_t *mat, matvar_t *matvar); -static int Mat_VarRead4(mat_t *mat, matvar_t *matvar); -static int Mat_VarReadData4(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, - int *edge); -static int Mat_VarReadDataLinear4(mat_t *mat, matvar_t *matvar, void *data, int start, int stride, - int edge); -static matvar_t *Mat_VarReadNextInfo4(mat_t *mat); - -#endif - -#ifndef MAT73_H -#define MAT73_H - -#if HAVE_HDF5 -static mat_t *Mat_Create73(const char *matname, const char *hdr_str); -static int Mat_Close73(mat_t *mat); -static int Mat_VarRead73(mat_t *mat, matvar_t *matvar); -static int Mat_VarReadData73(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, - int *edge); -static int Mat_VarReadDataLinear73(mat_t *mat, matvar_t *matvar, void *data, int start, int stride, - int edge); -static matvar_t *Mat_VarReadNextInfo73(mat_t *mat); -static int Mat_VarWrite73(mat_t *mat, matvar_t *matvar, int compress); -static int Mat_VarWriteAppend73(mat_t *mat, matvar_t *matvar, int compress, int dim); -#endif -#endif - -/* - *=================================================================== - * Private Functions - *=================================================================== - */ - -static char * -Mat_strdup(const char *s) -{ - size_t len = strlen(s) + 1; - char *d = (char *)malloc(len); - return d ? (char *)memcpy(d, s, len) : NULL; -} - -#define MAT_MKTEMP_DIR "/tmp/" -#define MAT_MKTEMP_TPL "XXXXXX" -#define MAT_MKTEMP_FILE "/temp.mat" - -#define MAT_MKTEMP_BUF_SIZE \ - (sizeof(MAT_MKTEMP_DIR) + sizeof(MAT_MKTEMP_TPL) + sizeof(MAT_MKTEMP_FILE) - 2) - -static char * -Mat_mktemp(char *path_buf, char *dir_buf) -{ - char *ret = NULL; - - *path_buf = '\0'; - *dir_buf = '\0'; - -#if ( defined(_WIN64) || defined(_WIN32) ) && !defined(__CYGWIN__) - strcpy(path_buf, MAT_MKTEMP_TPL); - if ( NULL != _mktemp(path_buf) ) - ret = path_buf; -#else - /* On Linux, using mktemp() causes annoying linker errors that can't be - suppressed. So, create a temporary directory with mkdtemp() instead, - and then just always use the same hardcoded filename inside that temp dir. - */ - strcpy(dir_buf, MAT_MKTEMP_DIR MAT_MKTEMP_TPL); - if ( NULL != mkdtemp(dir_buf) ) { - strcpy(path_buf, dir_buf); - strcat(path_buf, MAT_MKTEMP_FILE); - ret = path_buf; - } -#endif - - return ret; -} - -static int -ReadData(mat_t *mat, matvar_t *matvar) -{ - if ( mat == NULL || matvar == NULL || mat->fp == NULL ) - return MATIO_E_BAD_ARGUMENT; - else if ( mat->version == MAT_FT_MAT5 ) - return Mat_VarRead5(mat, matvar); -#if HAVE_HDF5 - else if ( mat->version == MAT_FT_MAT73 ) - return Mat_VarRead73(mat, matvar); -#endif - else if ( mat->version == MAT_FT_MAT4 ) - return Mat_VarRead4(mat, matvar); - return MATIO_E_FAIL_TO_IDENTIFY; -} - -static void -Mat_PrintNumber(enum matio_types type, void *data) -{ - switch ( type ) { - case MAT_T_DOUBLE: - printf("%g", *(double *)data); - break; - case MAT_T_SINGLE: - printf("%g", *(float *)data); - break; -#ifdef HAVE_MATIO_INT64_T - case MAT_T_INT64: -#if HAVE_INTTYPES_H - printf("%" PRIi64, *(mat_int64_t *)data); -#elif defined(_MSC_VER) && _MSC_VER >= 1200 - printf("%I64i", *(mat_int64_t *)data); -#elif defined(HAVE_LONG_LONG_INT) - printf("%lld", (long long)(*(mat_int64_t *)data)); -#else - printf("%ld", (long)(*(mat_int64_t *)data)); -#endif - break; -#endif -#ifdef HAVE_MATIO_UINT64_T - case MAT_T_UINT64: -#if HAVE_INTTYPES_H - printf("%" PRIu64, *(mat_uint64_t *)data); -#elif defined(_MSC_VER) && _MSC_VER >= 1200 - printf("%I64u", *(mat_uint64_t *)data); -#elif defined(HAVE_UNSIGNED_LONG_LONG_INT) - printf("%llu", (unsigned long long)(*(mat_uint64_t *)data)); -#else - printf("%lu", (unsigned long)(*(mat_uint64_t *)data)); -#endif - break; -#endif - case MAT_T_INT32: - printf("%d", *(mat_int32_t *)data); - break; - case MAT_T_UINT32: - printf("%u", *(mat_uint32_t *)data); - break; - case MAT_T_INT16: - printf("%hd", *(mat_int16_t *)data); - break; - case MAT_T_UINT16: - printf("%hu", *(mat_uint16_t *)data); - break; - case MAT_T_INT8: -#if defined(__GNUC__) && __STDC_VERSION__ >= 199901L - printf("%hhd", *(mat_int8_t *)data); -#else - printf("%hd", (mat_int16_t)(*(mat_int8_t *)data)); -#endif - break; - case MAT_T_UINT8: -#if defined(__GNUC__) && __STDC_VERSION__ >= 199901L - printf("%hhu", *(mat_uint8_t *)data); -#else - printf("%hu", (mat_uint16_t)(*(mat_uint8_t *)data)); -#endif - break; - default: - break; - } -} - -static mat_complex_split_t * -ComplexMalloc(size_t nbytes) -{ - mat_complex_split_t *complex_data = (mat_complex_split_t *)malloc(sizeof(*complex_data)); - if ( NULL != complex_data ) { - complex_data->Re = malloc(nbytes); - if ( NULL != complex_data->Re ) { - complex_data->Im = malloc(nbytes); - if ( NULL == complex_data->Im ) { - free(complex_data->Re); - free(complex_data); - complex_data = NULL; - } - } else { - free(complex_data); - complex_data = NULL; - } - } - - return complex_data; -} - -static void -ComplexFree(mat_complex_split_t *complex_data) -{ - free(complex_data->Re); - free(complex_data->Im); - free(complex_data); -} - -static enum matio_types -ClassType2DataType(enum matio_classes class_type) -{ - switch ( class_type ) { - case MAT_C_DOUBLE: - return MAT_T_DOUBLE; - case MAT_C_SINGLE: - return MAT_T_SINGLE; -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: - return MAT_T_INT64; -#endif -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: - return MAT_T_UINT64; -#endif - case MAT_C_INT32: - return MAT_T_INT32; - case MAT_C_UINT32: - return MAT_T_UINT32; - case MAT_C_INT16: - return MAT_T_INT16; - case MAT_C_UINT16: - return MAT_T_UINT16; - case MAT_C_INT8: - return MAT_T_INT8; - case MAT_C_CHAR: - return MAT_T_UINT8; - case MAT_C_UINT8: - return MAT_T_UINT8; - case MAT_C_CELL: - return MAT_T_CELL; - case MAT_C_STRUCT: - return MAT_T_STRUCT; - default: - return MAT_T_UNKNOWN; - } -} - -/** @brief Gets number of elements from a variable - * - * Gets number of elements from a variable by overflow-safe - * multiplication - * @ingroup MAT - * @param matvar MAT variable information - * @param nelems Number of elements - * @retval 0 on success - */ -static int -Mat_MulDims(const matvar_t *matvar, size_t *nelems) -{ - int i; - - if ( matvar->rank == 0 ) { - *nelems = 0; - return MATIO_E_NO_ERROR; - } - - for ( i = 0; i < matvar->rank; i++ ) { -#if HAVE_SAFE_MATH - if ( !psnip_safe_size_mul(nelems, *nelems, matvar->dims[i]) ) { - *nelems = 0; - return MATIO_E_INDEX_TOO_BIG; - } -#else - *nelems *= matvar->dims[i]; -#endif - } - - return MATIO_E_NO_ERROR; -} - -/** @brief Multiplies two unsigned integers - * - * @param res Result - * @param a First operand - * @param b Second operand - * @retval 0 on success - */ -static int -Mul(size_t *res, size_t a, size_t b) -{ -#if HAVE_SAFE_MATH - if ( !psnip_safe_size_mul(res, a, b) ) { - *res = 0; - return MATIO_E_INDEX_TOO_BIG; - } -#else - *res = a * b; -#endif - return MATIO_E_NO_ERROR; -} - -/** @brief Adds two unsigned integers - * - * @param res Result - * @param a First operand - * @param b Second operand - * @retval 0 on success - */ -static int -Add(size_t *res, size_t a, size_t b) -{ -#if HAVE_SAFE_MATH - if ( !psnip_safe_size_add(res, a, b) ) { - *res = 0; - return MATIO_E_INDEX_TOO_BIG; - } -#else - *res = a + b; -#endif - return MATIO_E_NO_ERROR; -} - -/** @brief Read from file and check success - * - * @param buf Buffer for reading - * @param size Element size in bytes - * @param count Element count - * @param fp File pointer - * @param[out] bytesread Number of bytes read from the file - * @retval 0 on success - */ -static int -Read(void *buf, size_t size, size_t count, FILE *fp, size_t *bytesread) -{ - const size_t readcount = fread(buf, size, count, fp); - int err = readcount != count; - if ( NULL != bytesread ) { - *bytesread += readcount * size; - } - if ( err ) { - Mat_Warning( - "Unexpected end-of-file: Read %zu" - " bytes, expected %zu" - " bytes", - readcount * size, count * size); - memset(buf, 0, count * size); - } - return err; -} - -/** @brief Check for End of file - * - * @param fp File pointer - * @param[out] fpos Current file position - * @retval 0 on success - */ -static int -IsEndOfFile(FILE *fp, long *fpos) -{ - int isEOF = feof(fp); - long fPos = ftell(fp); - if ( !isEOF ) { - if ( fPos == -1L ) { - Mat_Critical("Couldn't determine file position"); - } else { - (void)fseek(fp, 0, SEEK_END); - isEOF = fPos == ftell(fp); - if ( !isEOF ) { - (void)fseek(fp, fPos, SEEK_SET); - } - } - } - if ( NULL != fpos ) { - *fpos = fPos; - } - return isEOF; -} - -/* - *=================================================================== - * Public Functions - *=================================================================== - */ - -/** @brief Get the version of the library - * - * Gets the version number of the library - * @param major Pointer to store the library major version number - * @param minor Pointer to store the library minor version number - * @param release Pointer to store the library release version number - */ -void -Mat_GetLibraryVersion(int *major, int *minor, int *release) -{ - if ( NULL != major ) - *major = MATIO_MAJOR_VERSION; - if ( NULL != minor ) - *minor = MATIO_MINOR_VERSION; - if ( NULL != release ) - *release = MATIO_RELEASE_LEVEL; -} - -/** @brief Creates a new Matlab MAT file - * - * Tries to create a new Matlab MAT file with the given name and optional - * header string. If no header string is given, the default string - * is used containing the software, version, and date in it. If a header - * string is given, at most the first 116 characters is written to the file. - * The given header string need not be the full 116 characters, but MUST be - * NULL terminated. - * @ingroup MAT - * @param matname Name of MAT file to create - * @param hdr_str Optional header string, NULL to use default - * @param mat_file_ver MAT file version to create - * @return A pointer to the MAT file or NULL if it failed. This is not a - * simple FILE * and should not be used as one. - */ -mat_t * -Mat_CreateVer(const char *matname, const char *hdr_str, enum mat_ft mat_file_ver) -{ - mat_t *mat; - - switch ( mat_file_ver ) { - case MAT_FT_MAT4: - mat = Mat_Create4(matname); - break; - case MAT_FT_MAT5: - mat = Mat_Create5(matname, hdr_str); - break; - case MAT_FT_MAT73: -#if HAVE_HDF5 - mat = Mat_Create73(matname, hdr_str); -#else - mat = NULL; -#endif - break; - default: - mat = NULL; - break; - } - - return mat; -} - -/** @brief Opens an existing Matlab MAT file - * - * Tries to open a Matlab MAT file with the given name - * @ingroup MAT - * @param matname Name of MAT file to open - * @param mode File access mode (MAT_ACC_RDONLY,MAT_ACC_RDWR,etc). - * @return A pointer to the MAT file or NULL if it failed. This is not a - * simple FILE * and should not be used as one. - */ -mat_t * -Mat_Open(const char *matname, int mode) -{ - FILE *fp = NULL; - mat_int16_t tmp, tmp2; - mat_t *mat = NULL; - size_t bytesread = 0; - - if ( (mode & 0x01) == MAT_ACC_RDONLY ) { -#if defined(_WIN32) && defined(_MSC_VER) - wchar_t *wname = utf82u(matname); - if ( NULL != wname ) { - fp = _wfopen(wname, L"rb"); - free(wname); - } -#else - fp = fopen(matname, "rb"); -#endif - if ( !fp ) - return NULL; - } else if ( (mode & 0x01) == MAT_ACC_RDWR ) { -#if defined(_WIN32) && defined(_MSC_VER) - wchar_t *wname = utf82u(matname); - if ( NULL != wname ) { - fp = _wfopen(wname, L"r+b"); - free(wname); - } -#else - fp = fopen(matname, "r+b"); -#endif - if ( !fp ) { - mat = Mat_CreateVer(matname, NULL, (enum mat_ft)(mode & 0xfffffffe)); - return mat; - } - } else { - Mat_Critical("Invalid file open mode"); - return NULL; - } - - mat = (mat_t *)malloc(sizeof(*mat)); - if ( NULL == mat ) { - fclose(fp); - Mat_Critical("Couldn't allocate memory for the MAT file"); - return NULL; - } - - mat->fp = fp; - mat->header = (char *)calloc(128, sizeof(char)); - if ( NULL == mat->header ) { - free(mat); - fclose(fp); - Mat_Critical("Couldn't allocate memory for the MAT file header"); - return NULL; - } - mat->subsys_offset = (char *)calloc(8, sizeof(char)); - if ( NULL == mat->subsys_offset ) { - free(mat->header); - free(mat); - fclose(fp); - Mat_Critical("Couldn't allocate memory for the MAT file subsys offset"); - return NULL; - } - mat->filename = NULL; - mat->version = 0; - mat->byteswap = 0; - mat->num_datasets = 0; -#if HAVE_HDF5 - mat->refs_id = -1; -#endif - mat->dir = NULL; - - bytesread += fread(mat->header, 1, 116, fp); - mat->header[116] = '\0'; - bytesread += fread(mat->subsys_offset, 1, 8, fp); - bytesread += 2 * fread(&tmp2, 2, 1, fp); - bytesread += fread(&tmp, 1, 2, fp); - - if ( 128 == bytesread ) { - /* v5 and v7.3 files have at least 128 byte header */ - mat->byteswap = -1; - if ( tmp == 0x4d49 ) - mat->byteswap = 0; - else if ( tmp == 0x494d ) { - mat->byteswap = 1; - Mat_int16Swap(&tmp2); - } - - mat->version = (int)tmp2; - if ( (mat->version == 0x0100 || mat->version == 0x0200) && -1 != mat->byteswap ) { - mat->bof = ftell((FILE *)mat->fp); - if ( mat->bof == -1L ) { - free(mat->header); - free(mat->subsys_offset); - free(mat); - fclose(fp); - Mat_Critical("Couldn't determine file position"); - return NULL; - } - mat->next_index = 0; - } else { - mat->version = 0; - } - } - - if ( 0 == mat->version ) { - /* Maybe a V4 MAT file */ - matvar_t *var; - - free(mat->header); - free(mat->subsys_offset); - - mat->header = NULL; - mat->subsys_offset = NULL; - mat->fp = fp; - mat->version = MAT_FT_MAT4; - mat->byteswap = 0; - mat->mode = mode; - mat->bof = 0; - mat->next_index = 0; -#if HAVE_HDF5 - mat->refs_id = -1; -#endif - - Mat_Rewind(mat); - var = Mat_VarReadNextInfo4(mat); - if ( NULL == var && bytesread != 0 ) { /* Accept 0 bytes files as a valid V4 file */ - /* Does not seem to be a valid V4 file */ - Mat_Close(mat); - mat = NULL; - Mat_Critical("\"%s\" does not seem to be a valid MAT file", matname); - } else { - Mat_VarFree(var); - Mat_Rewind(mat); - } - } - - if ( NULL == mat ) - return mat; - - mat->filename = Mat_strdup(matname); - mat->mode = mode; - - if ( mat->version == 0x0200 ) { - fclose((FILE *)mat->fp); -#if HAVE_HDF5 - mat->fp = malloc(sizeof(hid_t)); - - if ( (mode & 0x01) == MAT_ACC_RDONLY ) - *(hid_t *)mat->fp = H5Fopen(matname, H5F_ACC_RDONLY, H5P_DEFAULT); - else if ( (mode & 0x01) == MAT_ACC_RDWR ) { - hid_t plist_ap; - plist_ap = H5Pcreate(H5P_FILE_ACCESS); -#if H5_VERSION_GE(1, 10, 2) - H5Pset_libver_bounds(plist_ap, H5F_LIBVER_EARLIEST, H5F_LIBVER_V18); -#endif - *(hid_t *)mat->fp = H5Fopen(matname, H5F_ACC_RDWR, plist_ap); - H5Pclose(plist_ap); - } else { - mat->fp = NULL; - Mat_Close(mat); - mat = NULL; - } - - if ( -1 < *(hid_t *)mat->fp ) { - H5G_info_t group_info; - herr_t herr; - memset(&group_info, 0, sizeof(group_info)); - herr = H5Gget_info(*(hid_t *)mat->fp, &group_info); - if ( herr < 0 ) { - Mat_Close(mat); - mat = NULL; - } else { - mat->num_datasets = (size_t)group_info.nlinks; - mat->refs_id = -1; - } - } -#else - mat->fp = NULL; - Mat_Close(mat); - mat = NULL; - Mat_Critical( - "No HDF5 support which is required to read the v7.3 " - "MAT file \"%s\"", - matname); -#endif - } - - return mat; -} - -/** @brief Closes an open Matlab MAT file - * - * Closes the given Matlab MAT file and frees any memory with it. - * @ingroup MAT - * @param mat Pointer to the MAT file - * @retval 0 on success - */ -int -Mat_Close(mat_t *mat) -{ - int err = MATIO_E_NO_ERROR; - - if ( NULL != mat ) { -#if HAVE_HDF5 - if ( mat->version == 0x0200 ) { - err = Mat_Close73(mat); - } -#endif - if ( NULL != mat->fp ) { - err = fclose((FILE *)mat->fp); - if ( 0 == err ) { - err = MATIO_E_NO_ERROR; - } else { - err = MATIO_E_FILESYSTEM_ERROR_ON_CLOSE; - } - } - if ( NULL != mat->header ) - free(mat->header); - if ( NULL != mat->subsys_offset ) - free(mat->subsys_offset); - if ( NULL != mat->filename ) - free(mat->filename); - if ( NULL != mat->dir ) { - size_t i; - for ( i = 0; i < mat->num_datasets; i++ ) { - if ( NULL != mat->dir[i] ) - free(mat->dir[i]); - } - free(mat->dir); - } - free(mat); - } else { - err = MATIO_E_BAD_ARGUMENT; - } - - return err; -} - -/** @brief Gets the filename for the given MAT file - * - * Gets the filename for the given MAT file - * @ingroup MAT - * @param mat Pointer to the MAT file - * @return MAT filename - */ -const char * -Mat_GetFilename(mat_t *mat) -{ - const char *filename = NULL; - if ( NULL != mat ) - filename = mat->filename; - return filename; -} - -/** @brief Gets the header for the given MAT file - * - * Gets the header for the given MAT file - * @ingroup MAT - * @param mat Pointer to the MAT file - * @return MAT header - */ -const char * -Mat_GetHeader(mat_t *mat) -{ - const char *header = NULL; - if ( NULL != mat ) - header = mat->header; - return header; -} - -/** @brief Gets the version of the given MAT file - * - * Gets the version of the given MAT file - * @ingroup MAT - * @param mat Pointer to the MAT file - * @return MAT file version - */ -enum mat_ft -Mat_GetVersion(mat_t *mat) -{ - enum mat_ft file_type = MAT_FT_UNDEFINED; - if ( NULL != mat ) - file_type = (enum mat_ft)mat->version; - return file_type; -} - -/** @brief Gets a list of the variables of a MAT file - * - * Gets a list of the variables of a MAT file - * @ingroup MAT - * @param mat Pointer to the MAT file - * @param[out] n Number of variables in the given MAT file - * @return Array of variable names - */ -char ** -Mat_GetDir(mat_t *mat, size_t *n) -{ - char **dir = NULL; - - if ( NULL == n ) - return dir; - - if ( NULL == mat ) { - *n = 0; - return dir; - } - - if ( NULL == mat->dir ) { - matvar_t *matvar = NULL; - - if ( mat->version == MAT_FT_MAT73 ) { - size_t i = 0; - size_t fpos = mat->next_index; - if ( mat->num_datasets == 0 ) { - *n = 0; - return dir; - } - mat->dir = (char **)calloc(mat->num_datasets, sizeof(char *)); - if ( NULL == mat->dir ) { - *n = 0; - Mat_Critical("Couldn't allocate memory for the directory"); - return dir; - } - mat->next_index = 0; - while ( mat->next_index < mat->num_datasets ) { - matvar = Mat_VarReadNextInfo(mat); - if ( NULL != matvar ) { - if ( NULL != matvar->name ) { - mat->dir[i++] = Mat_strdup(matvar->name); - } - Mat_VarFree(matvar); - } else { - Mat_Critical("An error occurred in reading the MAT file"); - break; - } - } - mat->next_index = fpos; - *n = i; - } else { - long fpos = ftell((FILE *)mat->fp); - if ( fpos == -1L ) { - *n = 0; - Mat_Critical("Couldn't determine file position"); - return dir; - } - (void)fseek((FILE *)mat->fp, mat->bof, SEEK_SET); - mat->num_datasets = 0; - do { - matvar = Mat_VarReadNextInfo(mat); - if ( NULL != matvar ) { - if ( NULL != matvar->name ) { - if ( NULL == mat->dir ) { - dir = (char **)malloc(sizeof(char *)); - } else { - dir = (char **)realloc(mat->dir, - (mat->num_datasets + 1) * (sizeof(char *))); - } - if ( NULL != dir ) { - mat->dir = dir; - mat->dir[mat->num_datasets++] = Mat_strdup(matvar->name); - } else { - Mat_Critical("Couldn't allocate memory for the directory"); - break; - } - } - Mat_VarFree(matvar); - } else if ( !IsEndOfFile((FILE *)mat->fp, NULL) ) { - Mat_Critical("An error occurred in reading the MAT file"); - break; - } - } while ( !IsEndOfFile((FILE *)mat->fp, NULL) ); - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - *n = mat->num_datasets; - } - } else { - if ( mat->version == MAT_FT_MAT73 ) { - *n = 0; - while ( *n < mat->num_datasets && NULL != mat->dir[*n] ) { - (*n)++; - } - } else { - *n = mat->num_datasets; - } - } - dir = mat->dir; - return dir; -} - -/** @brief Rewinds a Matlab MAT file to the first variable - * - * Rewinds a Matlab MAT file to the first variable - * @ingroup MAT - * @param mat Pointer to the MAT file - * @retval 0 on success - */ -int -Mat_Rewind(mat_t *mat) -{ - int err = MATIO_E_NO_ERROR; - - switch ( mat->version ) { - case MAT_FT_MAT5: - (void)fseek((FILE *)mat->fp, 128L, SEEK_SET); - break; - case MAT_FT_MAT73: - mat->next_index = 0; - break; - case MAT_FT_MAT4: - (void)fseek((FILE *)mat->fp, 0L, SEEK_SET); - break; - default: - err = MATIO_E_FAIL_TO_IDENTIFY; - break; - } - - return err; -} - -/** @brief Returns the size of a Matlab Class - * - * Returns the size (in bytes) of the matlab class class_type - * @ingroup MAT - * @param class_type Matlab class type (MAT_C_*) - * @returns Size of the class - */ -size_t -Mat_SizeOfClass(int class_type) -{ - switch ( class_type ) { - case MAT_C_DOUBLE: - return sizeof(double); - case MAT_C_SINGLE: - return sizeof(float); -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: - return sizeof(mat_int64_t); -#endif -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: - return sizeof(mat_uint64_t); -#endif - case MAT_C_INT32: - return sizeof(mat_int32_t); - case MAT_C_UINT32: - return sizeof(mat_uint32_t); - case MAT_C_INT16: - return sizeof(mat_int16_t); - case MAT_C_UINT16: - return sizeof(mat_uint16_t); - case MAT_C_INT8: - return sizeof(mat_int8_t); - case MAT_C_UINT8: - return sizeof(mat_uint8_t); - case MAT_C_CHAR: - return sizeof(mat_int16_t); - default: - return 0; - } -} - -/* - *=================================================================== - * MAT Variable Functions - *=================================================================== - */ - -/** @brief Allocates memory for a new matvar_t and initializes all the fields - * - * @ingroup MAT - * @return A newly allocated matvar_t - */ -matvar_t * -Mat_VarCalloc(void) -{ - matvar_t *matvar; - - matvar = (matvar_t *)malloc(sizeof(*matvar)); - - if ( NULL != matvar ) { - matvar->nbytes = 0; - matvar->rank = 0; - matvar->data_type = MAT_T_UNKNOWN; - matvar->data_size = 0; - matvar->class_type = MAT_C_EMPTY; - matvar->isComplex = 0; - matvar->isGlobal = 0; - matvar->isLogical = 0; - matvar->dims = NULL; - matvar->name = NULL; - matvar->data = NULL; - matvar->mem_conserve = 0; - matvar->compression = MAT_COMPRESSION_NONE; - matvar->internal = (struct matvar_internal *)malloc(sizeof(*matvar->internal)); - if ( NULL == matvar->internal ) { - free(matvar); - matvar = NULL; - } else { -#if HAVE_HDF5 - matvar->internal->hdf5_name = NULL; - matvar->internal->hdf5_ref = 0; - matvar->internal->id = -1; -#endif - matvar->internal->datapos = 0; - matvar->internal->num_fields = 0; - matvar->internal->fieldnames = NULL; -#if HAVE_ZLIB - matvar->internal->z = NULL; - matvar->internal->data = NULL; -#endif - } - } - - return matvar; -} - -/** @brief Creates a MAT Variable with the given name and (optionally) data - * - * Creates a MAT variable that can be written to a Matlab MAT file with the - * given name, data type, dimensions and data. Rank should always be 2 or more. - * i.e. Scalar values would have rank=2 and dims[2] = {1,1}. Data type is - * one of the MAT_T types. MAT adds MAT_T_STRUCT and MAT_T_CELL to create - * Structures and Cell Arrays respectively. For MAT_T_STRUCT, data should be a - * NULL terminated array of matvar_t * variables (i.e. for a 3x2 structure with - * 10 fields, there should be 61 matvar_t * variables where the last one is - * NULL). For cell arrays, the NULL termination isn't necessary. So to create - * a cell array of size 3x2, data would be the address of an array of 6 - * matvar_t * variables. - * - * EXAMPLE: - * To create a struct of size 3x2 with 3 fields: - * @code - * int rank=2, dims[2] = {3,2}, nfields = 3; - * matvar_t **vars; - * - * vars = malloc((3*2*nfields+1)*sizeof(matvar_t *)); - * vars[0] = Mat_VarCreate(...); - * : - * vars[3*2*nfields-1] = Mat_VarCreate(...); - * vars[3*2*nfields] = NULL; - * @endcode - * - * EXAMPLE: - * To create a cell array of size 3x2: - * @code - * int rank=2, dims[2] = {3,2}; - * matvar_t **vars; - * - * vars = malloc(3*2*sizeof(matvar_t *)); - * vars[0] = Mat_VarCreate(...); - * : - * vars[5] = Mat_VarCreate(...); - * @endcode - * - * @ingroup MAT - * @param name Name of the variable to create - * @param class_type class type of the variable in Matlab(one of the mx Classes) - * @param data_type data type of the variable (one of the MAT_T_ Types) - * @param rank Rank of the variable - * @param dims array of dimensions of the variable of size rank - * @param data pointer to the data - * @param opt 0, or bitwise or of the following options: - * - MAT_F_DONT_COPY_DATA to just use the pointer to the data and not copy the - * data itself. Note that the pointer should not be freed until you are - * done with the mat variable. The Mat_VarFree function will NOT free - * data that was created with MAT_F_DONT_COPY_DATA, so free it yourself. - * - MAT_F_COMPLEX to specify that the data is complex. The data variable - * should be a pointer to a mat_complex_split_t type. - * - MAT_F_GLOBAL to assign the variable as a global variable - * - MAT_F_LOGICAL to specify that it is a logical variable - * @return A MAT variable that can be written to a file or otherwise used - */ -matvar_t * -Mat_VarCreate(const char *name, enum matio_classes class_type, enum matio_types data_type, int rank, - size_t *dims, void *data, int opt) -{ - size_t nelems = 1, data_size; - matvar_t *matvar = NULL; - int j, err; - - if ( dims == NULL ) - return NULL; - - matvar = Mat_VarCalloc(); - if ( NULL == matvar ) - return NULL; - - matvar->compression = MAT_COMPRESSION_NONE; - matvar->isComplex = opt & MAT_F_COMPLEX; - matvar->isGlobal = opt & MAT_F_GLOBAL; - matvar->isLogical = opt & MAT_F_LOGICAL; - if ( name ) - matvar->name = Mat_strdup(name); - matvar->rank = rank; - matvar->dims = (size_t *)malloc(matvar->rank * sizeof(*matvar->dims)); - for ( j = 0; j < matvar->rank; j++ ) { - matvar->dims[j] = dims[j]; - nelems *= dims[j]; - } - matvar->class_type = class_type; - matvar->data_type = data_type; - switch ( data_type ) { - case MAT_T_INT8: - data_size = 1; - break; - case MAT_T_UINT8: - data_size = 1; - break; - case MAT_T_INT16: - data_size = 2; - break; - case MAT_T_UINT16: - data_size = 2; - break; - case MAT_T_INT64: - data_size = 8; - break; - case MAT_T_UINT64: - data_size = 8; - break; - case MAT_T_INT32: - data_size = 4; - break; - case MAT_T_UINT32: - data_size = 4; - break; - case MAT_T_SINGLE: - data_size = sizeof(float); - break; - case MAT_T_DOUBLE: - data_size = sizeof(double); - break; - case MAT_T_UTF8: - data_size = 1; - break; - case MAT_T_UTF16: - data_size = 2; - break; - case MAT_T_UTF32: - data_size = 4; - break; - case MAT_T_CELL: - data_size = sizeof(matvar_t **); - break; - case MAT_T_STRUCT: { - data_size = sizeof(matvar_t **); - if ( data != NULL ) { - matvar_t **fields = (matvar_t **)data; - size_t nfields = 0; - while ( fields[nfields] != NULL ) - nfields++; - if ( nelems ) - nfields /= nelems; - matvar->internal->num_fields = nfields; - if ( nfields ) { - size_t i; - matvar->internal->fieldnames = - (char **)calloc(nfields, sizeof(*matvar->internal->fieldnames)); - for ( i = 0; i < nfields; i++ ) - matvar->internal->fieldnames[i] = Mat_strdup(fields[i]->name); - err = Mul(&nelems, nelems, nfields); - if ( err ) { - Mat_VarFree(matvar); - Mat_Critical("Integer multiplication overflow"); - return NULL; - } - } - } - break; - } - default: - Mat_VarFree(matvar); - Mat_Critical("Unrecognized data_type"); - return NULL; - } - if ( matvar->class_type == MAT_C_SPARSE ) { - matvar->data_size = sizeof(mat_sparse_t); - matvar->nbytes = matvar->data_size; - } else if ( matvar->class_type == MAT_C_CHAR && matvar->data_type == MAT_T_UTF8 ) { - size_t k = 0; - if ( data != NULL ) { - size_t i; - mat_uint8_t *ptr = (mat_uint8_t *)data; - for ( i = 0; i < nelems; i++ ) { - const mat_uint8_t c = ptr[k]; - if ( c <= 0x7F ) { - k++; - } else if ( (c & 0xE0) == 0xC0 ) { - k += 2; - } else if ( (c & 0xF0) == 0xE0 ) { - k += 3; - } else if ( (c & 0xF8) == 0xF0 ) { - k += 4; - } - } - } - matvar->nbytes = k; - matvar->data_size = (int)data_size; - } else { - matvar->data_size = (int)data_size; - err = Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err ) { - Mat_VarFree(matvar); - Mat_Critical("Integer multiplication overflow"); - return NULL; - } - } - if ( data == NULL ) { - if ( MAT_C_CELL == matvar->class_type && nelems > 0 ) - matvar->data = calloc(nelems, sizeof(matvar_t *)); - } else if ( opt & MAT_F_DONT_COPY_DATA ) { - matvar->data = data; - matvar->mem_conserve = 1; - } else if ( MAT_C_SPARSE == matvar->class_type ) { - mat_sparse_t *sparse_data, *sparse_data_in; - - sparse_data_in = (mat_sparse_t *)data; - sparse_data = (mat_sparse_t *)malloc(sizeof(mat_sparse_t)); - if ( NULL != sparse_data ) { - sparse_data->nzmax = sparse_data_in->nzmax; - sparse_data->nir = sparse_data_in->nir; - sparse_data->njc = sparse_data_in->njc; - sparse_data->ndata = sparse_data_in->ndata; - sparse_data->ir = (mat_uint32_t *)malloc(sparse_data->nir * sizeof(*sparse_data->ir)); - if ( NULL != sparse_data->ir ) - memcpy(sparse_data->ir, sparse_data_in->ir, - sparse_data->nir * sizeof(*sparse_data->ir)); - sparse_data->jc = (mat_uint32_t *)malloc(sparse_data->njc * sizeof(*sparse_data->jc)); - if ( NULL != sparse_data->jc ) - memcpy(sparse_data->jc, sparse_data_in->jc, - sparse_data->njc * sizeof(*sparse_data->jc)); - if ( matvar->isComplex ) { - sparse_data->data = malloc(sizeof(mat_complex_split_t)); - if ( NULL != sparse_data->data ) { - mat_complex_split_t *complex_data, *complex_data_in; - complex_data = (mat_complex_split_t *)sparse_data->data; - complex_data_in = (mat_complex_split_t *)sparse_data_in->data; - complex_data->Re = malloc(sparse_data->ndata * data_size); - complex_data->Im = malloc(sparse_data->ndata * data_size); - if ( NULL != complex_data->Re ) - memcpy(complex_data->Re, complex_data_in->Re, - sparse_data->ndata * data_size); - if ( NULL != complex_data->Im ) - memcpy(complex_data->Im, complex_data_in->Im, - sparse_data->ndata * data_size); - } - } else { - sparse_data->data = malloc(sparse_data->ndata * data_size); - if ( NULL != sparse_data->data ) - memcpy(sparse_data->data, sparse_data_in->data, sparse_data->ndata * data_size); - } - } - matvar->data = sparse_data; - } else { - if ( matvar->isComplex ) { - matvar->data = malloc(sizeof(mat_complex_split_t)); - if ( NULL != matvar->data && matvar->nbytes > 0 ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)matvar->data; - mat_complex_split_t *complex_data_in = (mat_complex_split_t *)data; - - complex_data->Re = malloc(matvar->nbytes); - complex_data->Im = malloc(matvar->nbytes); - if ( NULL != complex_data->Re ) - memcpy(complex_data->Re, complex_data_in->Re, matvar->nbytes); - if ( NULL != complex_data->Im ) - memcpy(complex_data->Im, complex_data_in->Im, matvar->nbytes); - } - } else if ( matvar->nbytes > 0 ) { - matvar->data = malloc(matvar->nbytes); - if ( NULL != matvar->data ) - memcpy(matvar->data, data, matvar->nbytes); - } - matvar->mem_conserve = 0; - } - - return matvar; -} - -/** @brief Copies a file - * - * @param src source file path - * @param dst destination file path - * @retval 0 on success - */ -static int -Mat_CopyFile(const char *src, const char *dst) -{ - size_t len; - char buf[BUFSIZ] = {'\0'}; - FILE *in = NULL; - FILE *out = NULL; - -#if defined(_WIN32) && defined(_MSC_VER) - { - wchar_t *wname = utf82u(src); - if ( NULL != wname ) { - in = _wfopen(wname, L"rb"); - free(wname); - } - } -#else - in = fopen(src, "rb"); -#endif - if ( in == NULL ) { - Mat_Critical("Cannot open file \"%s\" for reading.", src); - return MATIO_E_FILESYSTEM_COULD_NOT_OPEN; - } - -#if defined(_WIN32) && defined(_MSC_VER) - { - wchar_t *wname = utf82u(dst); - if ( NULL != wname ) { - out = _wfopen(wname, L"wb"); - free(wname); - } - } -#else - out = fopen(dst, "wb"); -#endif - if ( out == NULL ) { - fclose(in); - Mat_Critical("Cannot open file \"%s\" for writing.", dst); - return MATIO_E_FILESYSTEM_COULD_NOT_OPEN; - } - - while ( (len = fread(buf, sizeof(char), BUFSIZ, in)) > 0 ) { - if ( len != fwrite(buf, sizeof(char), len, out) ) { - fclose(in); - fclose(out); - Mat_Critical("Error writing to file \"%s\".", dst); - return MATIO_E_GENERIC_WRITE_ERROR; - } - } - fclose(in); - fclose(out); - return MATIO_E_NO_ERROR; -} - -/** @brief Deletes a variable from a file - * - * @ingroup MAT - * @param mat Pointer to the mat_t file structure - * @param name Name of the variable to delete - * @returns 0 on success - */ -int -Mat_VarDelete(mat_t *mat, const char *name) -{ - int err = MATIO_E_BAD_ARGUMENT; - char path_buf[MAT_MKTEMP_BUF_SIZE]; - char dir_buf[MAT_MKTEMP_BUF_SIZE]; - - if ( NULL == mat || NULL == name ) - return err; - - if ( NULL != Mat_mktemp(path_buf, dir_buf) ) { - enum mat_ft mat_file_ver; - mat_t *tmp; - - switch ( mat->version ) { - case 0x0100: - mat_file_ver = MAT_FT_MAT5; - break; - case 0x0200: - mat_file_ver = MAT_FT_MAT73; - break; - case 0x0010: - mat_file_ver = MAT_FT_MAT4; - break; - default: - mat_file_ver = MAT_FT_DEFAULT; - break; - } - - tmp = Mat_CreateVer(path_buf, mat->header, mat_file_ver); - if ( tmp != NULL ) { - matvar_t *matvar; - char **dir; - size_t n; - - Mat_Rewind(mat); - while ( NULL != (matvar = Mat_VarReadNext(mat)) ) { - if ( 0 != strcmp(matvar->name, name) ) - err = Mat_VarWrite(tmp, matvar, matvar->compression); - else - err = MATIO_E_NO_ERROR; - Mat_VarFree(matvar); - } - dir = tmp->dir; /* Keep directory for later assignment */ - tmp->dir = NULL; - n = tmp->num_datasets; - Mat_Close(tmp); - - if ( MATIO_E_NO_ERROR == err ) { - char *new_name = Mat_strdup(mat->filename); -#if HAVE_HDF5 - if ( mat_file_ver == MAT_FT_MAT73 ) { - err = Mat_Close73(mat); - } -#endif - if ( mat->fp != NULL ) { - fclose((FILE *)mat->fp); - mat->fp = NULL; - } - - if ( (err = Mat_CopyFile(path_buf, new_name)) != MATIO_E_NO_ERROR ) { - if ( NULL != dir ) { - size_t i; - for ( i = 0; i < n; i++ ) { - if ( dir[i] ) - free(dir[i]); - } - free(dir); - } - Mat_Critical("Cannot copy file from \"%s\" to \"%s\".", path_buf, new_name); - } else if ( (err = remove(path_buf)) != 0 ) { - err = MATIO_E_UNKNOWN_ERROR; - if ( NULL != dir ) { - size_t i; - for ( i = 0; i < n; i++ ) { - if ( dir[i] ) - free(dir[i]); - } - free(dir); - } - Mat_Critical("Cannot remove file \"%s\".", path_buf); - } else if ( *dir_buf != '\0' && (err = remove(dir_buf)) != 0 ) { - err = MATIO_E_UNKNOWN_ERROR; - if ( NULL != dir ) { - size_t i; - for ( i = 0; i < n; i++ ) { - if ( dir[i] ) - free(dir[i]); - } - free(dir); - } - Mat_Critical("Cannot remove directory \"%s\".", dir_buf); - } else { - tmp = Mat_Open(new_name, mat->mode); - if ( NULL != tmp ) { - if ( mat->header ) - free(mat->header); - if ( mat->subsys_offset ) - free(mat->subsys_offset); - if ( mat->filename ) - free(mat->filename); - if ( mat->dir ) { - size_t i; - for ( i = 0; i < mat->num_datasets; i++ ) { - if ( mat->dir[i] ) - free(mat->dir[i]); - } - free(mat->dir); - } - memcpy(mat, tmp, sizeof(mat_t)); - free(tmp); - mat->num_datasets = n; - mat->dir = dir; - } else { - Mat_Critical("Cannot open file \"%s\".", new_name); - err = MATIO_E_FILESYSTEM_COULD_NOT_OPEN; - } - } - free(new_name); - } else if ( (err = remove(path_buf)) != 0 ) { - err = MATIO_E_UNKNOWN_ERROR; - Mat_Critical("Cannot remove file \"%s\".", path_buf); - } else if ( *dir_buf != '\0' && (err = remove(dir_buf)) != 0 ) { - err = MATIO_E_UNKNOWN_ERROR; - Mat_Critical("Cannot remove directory \"%s\".", dir_buf); - } - } else { - err = MATIO_E_UNKNOWN_ERROR; - } - } else { - Mat_Critical("Cannot create a unique file name."); - err = MATIO_E_FILESYSTEM_COULD_NOT_OPEN_TEMPORARY; - } - - return err; -} - -/** @brief Duplicates a matvar_t structure - * - * Provides a clean function for duplicating a matvar_t structure. - * @ingroup MAT - * @param in pointer to the matvar_t structure to be duplicated - * @param opt 0 does a shallow duplicate and only assigns the data pointer to - * the duplicated array. 1 will do a deep duplicate and actually - * duplicate the contents of the data. Warning: If you do a shallow - * copy and free both structures, the data will be freed twice and - * memory will be corrupted. This may be fixed in a later release. - * @returns Pointer to the duplicated matvar_t structure. - */ -matvar_t * -Mat_VarDuplicate(const matvar_t *in, int opt) -{ - matvar_t *out; - size_t i; - - out = Mat_VarCalloc(); - if ( out == NULL ) - return NULL; - - out->nbytes = in->nbytes; - out->rank = in->rank; - out->data_type = in->data_type; - out->data_size = in->data_size; - out->class_type = in->class_type; - out->isComplex = in->isComplex; - out->isGlobal = in->isGlobal; - out->isLogical = in->isLogical; - out->mem_conserve = in->mem_conserve; - out->compression = in->compression; - - if ( NULL != in->name ) { - size_t len = strlen(in->name) + 1; - out->name = (char *)malloc(len); - if ( NULL != out->name ) - memcpy(out->name, in->name, len); - } - - out->dims = (size_t *)malloc(in->rank * sizeof(*out->dims)); - if ( out->dims != NULL ) - memcpy(out->dims, in->dims, in->rank * sizeof(*out->dims)); - - if ( NULL != in->internal ) { -#if HAVE_HDF5 - if ( NULL != in->internal->hdf5_name ) - out->internal->hdf5_name = Mat_strdup(in->internal->hdf5_name); - - out->internal->hdf5_ref = in->internal->hdf5_ref; - out->internal->id = in->internal->id; -#endif - out->internal->datapos = in->internal->datapos; -#if HAVE_ZLIB - out->internal->z = NULL; - out->internal->data = NULL; -#endif - out->internal->num_fields = in->internal->num_fields; - if ( NULL != in->internal->fieldnames && in->internal->num_fields > 0 ) { - out->internal->fieldnames = - (char **)calloc(in->internal->num_fields, sizeof(*in->internal->fieldnames)); - if ( NULL != out->internal->fieldnames ) { - for ( i = 0; i < in->internal->num_fields; i++ ) { - if ( NULL != in->internal->fieldnames[i] ) - out->internal->fieldnames[i] = Mat_strdup(in->internal->fieldnames[i]); - } - } - } - -#if HAVE_ZLIB - if ( in->internal->z != NULL ) { - out->internal->z = (z_streamp)malloc(sizeof(z_stream)); - if ( NULL != out->internal->z ) { - int err = inflateCopy(out->internal->z, in->internal->z); - if ( err != Z_OK ) { - free(out->internal->z); - out->internal->z = NULL; - } - } - } - if ( in->internal->data != NULL ) { - if ( in->class_type == MAT_C_SPARSE ) { - out->internal->data = malloc(sizeof(mat_sparse_t)); - if ( out->internal->data != NULL ) { - mat_sparse_t *out_sparse = (mat_sparse_t *)out->internal->data; - mat_sparse_t *in_sparse = (mat_sparse_t *)in->internal->data; - out_sparse->nzmax = in_sparse->nzmax; - out_sparse->nir = in_sparse->nir; - out_sparse->ir = - (mat_uint32_t *)malloc(in_sparse->nir * sizeof(*out_sparse->ir)); - if ( out_sparse->ir != NULL ) - memcpy(out_sparse->ir, in_sparse->ir, - in_sparse->nir * sizeof(*out_sparse->ir)); - out_sparse->njc = in_sparse->njc; - out_sparse->jc = - (mat_uint32_t *)malloc(in_sparse->njc * sizeof(*out_sparse->jc)); - if ( out_sparse->jc != NULL ) - memcpy(out_sparse->jc, in_sparse->jc, - in_sparse->njc * sizeof(*out_sparse->jc)); - out_sparse->ndata = in_sparse->ndata; - if ( out->isComplex && NULL != in_sparse->data ) { - out_sparse->data = malloc(sizeof(mat_complex_split_t)); - if ( out_sparse->data != NULL ) { - mat_complex_split_t *out_data = (mat_complex_split_t *)out_sparse->data; - mat_complex_split_t *in_data = (mat_complex_split_t *)in_sparse->data; - out_data->Re = malloc(in_sparse->ndata * Mat_SizeOf(in->data_type)); - if ( NULL != out_data->Re ) - memcpy(out_data->Re, in_data->Re, - in_sparse->ndata * Mat_SizeOf(in->data_type)); - out_data->Im = malloc(in_sparse->ndata * Mat_SizeOf(in->data_type)); - if ( NULL != out_data->Im ) - memcpy(out_data->Im, in_data->Im, - in_sparse->ndata * Mat_SizeOf(in->data_type)); - } - } else if ( in_sparse->data != NULL ) { - out_sparse->data = malloc(in_sparse->ndata * Mat_SizeOf(in->data_type)); - if ( NULL != out_sparse->data ) - memcpy(out_sparse->data, in_sparse->data, - in_sparse->ndata * Mat_SizeOf(in->data_type)); - } - } - } else if ( out->isComplex ) { - out->internal->data = malloc(sizeof(mat_complex_split_t)); - if ( out->internal->data != NULL ) { - mat_complex_split_t *out_data = (mat_complex_split_t *)out->internal->data; - mat_complex_split_t *in_data = (mat_complex_split_t *)in->internal->data; - out_data->Re = malloc(out->nbytes); - if ( NULL != out_data->Re ) - memcpy(out_data->Re, in_data->Re, out->nbytes); - out_data->Im = malloc(out->nbytes); - if ( NULL != out_data->Im ) - memcpy(out_data->Im, in_data->Im, out->nbytes); - } - } else if ( NULL != (out->internal->data = malloc(in->nbytes)) ) { - memcpy(out->internal->data, in->internal->data, in->nbytes); - } - } -#endif - } else { - free(out->internal); - out->internal = NULL; - } - - if ( !opt ) { - out->data = in->data; - } else if ( (in->data != NULL) && (in->class_type == MAT_C_STRUCT) ) { - out->data = malloc(in->nbytes); - if ( out->data != NULL && in->data_size > 0 ) { - size_t nfields = in->nbytes / in->data_size; - matvar_t **infields = (matvar_t **)in->data; - matvar_t **outfields = (matvar_t **)out->data; - for ( i = 0; i < nfields; i++ ) { - outfields[i] = Mat_VarDuplicate(infields[i], opt); - } - } - } else if ( (in->data != NULL) && (in->class_type == MAT_C_CELL) ) { - out->data = malloc(in->nbytes); - if ( out->data != NULL && in->data_size > 0 ) { - size_t nelems = in->nbytes / in->data_size; - matvar_t **incells = (matvar_t **)in->data; - matvar_t **outcells = (matvar_t **)out->data; - for ( i = 0; i < nelems; i++ ) { - outcells[i] = Mat_VarDuplicate(incells[i], opt); - } - } - } else if ( (in->data != NULL) && (in->class_type == MAT_C_SPARSE) ) { - out->data = malloc(sizeof(mat_sparse_t)); - if ( out->data != NULL ) { - mat_sparse_t *out_sparse = (mat_sparse_t *)out->data; - mat_sparse_t *in_sparse = (mat_sparse_t *)in->data; - out_sparse->nzmax = in_sparse->nzmax; - out_sparse->nir = in_sparse->nir; - out_sparse->ir = (mat_uint32_t *)malloc(in_sparse->nir * sizeof(*out_sparse->ir)); - if ( out_sparse->ir != NULL ) - memcpy(out_sparse->ir, in_sparse->ir, in_sparse->nir * sizeof(*out_sparse->ir)); - out_sparse->njc = in_sparse->njc; - out_sparse->jc = (mat_uint32_t *)malloc(in_sparse->njc * sizeof(*out_sparse->jc)); - if ( out_sparse->jc != NULL ) - memcpy(out_sparse->jc, in_sparse->jc, in_sparse->njc * sizeof(*out_sparse->jc)); - out_sparse->ndata = in_sparse->ndata; - if ( out->isComplex && NULL != in_sparse->data ) { - out_sparse->data = malloc(sizeof(mat_complex_split_t)); - if ( out_sparse->data != NULL ) { - mat_complex_split_t *out_data = (mat_complex_split_t *)out_sparse->data; - mat_complex_split_t *in_data = (mat_complex_split_t *)in_sparse->data; - out_data->Re = malloc(in_sparse->ndata * Mat_SizeOf(in->data_type)); - if ( NULL != out_data->Re ) - memcpy(out_data->Re, in_data->Re, - in_sparse->ndata * Mat_SizeOf(in->data_type)); - out_data->Im = malloc(in_sparse->ndata * Mat_SizeOf(in->data_type)); - if ( NULL != out_data->Im ) - memcpy(out_data->Im, in_data->Im, - in_sparse->ndata * Mat_SizeOf(in->data_type)); - } - } else if ( in_sparse->data != NULL ) { - out_sparse->data = malloc(in_sparse->ndata * Mat_SizeOf(in->data_type)); - if ( NULL != out_sparse->data ) - memcpy(out_sparse->data, in_sparse->data, - in_sparse->ndata * Mat_SizeOf(in->data_type)); - } else { - out_sparse->data = NULL; - } - } - } else if ( in->data != NULL ) { - if ( out->isComplex ) { - out->data = malloc(sizeof(mat_complex_split_t)); - if ( out->data != NULL ) { - mat_complex_split_t *out_data = (mat_complex_split_t *)out->data; - mat_complex_split_t *in_data = (mat_complex_split_t *)in->data; - out_data->Re = malloc(out->nbytes); - if ( NULL != out_data->Re ) - memcpy(out_data->Re, in_data->Re, out->nbytes); - out_data->Im = malloc(out->nbytes); - if ( NULL != out_data->Im ) - memcpy(out_data->Im, in_data->Im, out->nbytes); - } - } else { - out->data = malloc(in->nbytes); - if ( out->data != NULL ) - memcpy(out->data, in->data, in->nbytes); - } - } - - return out; -} - -/** @brief Frees all the allocated memory associated with the structure - * - * Frees memory used by a MAT variable. Frees the data associated with a - * MAT variable if it's non-NULL and MAT_F_DONT_COPY_DATA was not used. - * @ingroup MAT - * @param matvar Pointer to the matvar_t structure - */ -void -Mat_VarFree(matvar_t *matvar) -{ - size_t nelems = 0; - int err; - - if ( NULL == matvar ) - return; - if ( NULL != matvar->dims ) { - nelems = 1; - err = Mat_MulDims(matvar, &nelems); - free(matvar->dims); - } else { - err = MATIO_E_BAD_ARGUMENT; - } - if ( NULL != matvar->data ) { - switch ( matvar->class_type ) { - case MAT_C_STRUCT: - if ( !matvar->mem_conserve ) { - if ( MATIO_E_NO_ERROR == err ) { - matvar_t **fields = (matvar_t **)matvar->data; - size_t nelems_x_nfields; - err = Mul(&nelems_x_nfields, nelems, matvar->internal->num_fields); - if ( MATIO_E_NO_ERROR == err && nelems_x_nfields > 0 ) { - size_t i; - for ( i = 0; i < nelems_x_nfields; i++ ) - Mat_VarFree(fields[i]); - } - } - free(matvar->data); - } - break; - case MAT_C_CELL: - if ( !matvar->mem_conserve ) { - if ( MATIO_E_NO_ERROR == err ) { - matvar_t **cells = (matvar_t **)matvar->data; - size_t i; - for ( i = 0; i < nelems; i++ ) - Mat_VarFree(cells[i]); - } - free(matvar->data); - } - break; - case MAT_C_SPARSE: - if ( !matvar->mem_conserve ) { - mat_sparse_t *sparse; - sparse = (mat_sparse_t *)matvar->data; - if ( sparse->ir != NULL ) - free(sparse->ir); - if ( sparse->jc != NULL ) - free(sparse->jc); - if ( matvar->isComplex && NULL != sparse->data ) { - ComplexFree((mat_complex_split_t *)sparse->data); - } else if ( sparse->data != NULL ) { - free(sparse->data); - } - free(sparse); - } - break; - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: - case MAT_C_CHAR: - if ( !matvar->mem_conserve ) { - if ( matvar->isComplex ) { - ComplexFree((mat_complex_split_t *)matvar->data); - } else { - free(matvar->data); - } - } - break; - case MAT_C_FUNCTION: - if ( !matvar->mem_conserve ) { - free(matvar->data); - } - break; - case MAT_C_EMPTY: - case MAT_C_OBJECT: - case MAT_C_OPAQUE: - break; - } - } - - if ( NULL != matvar->internal ) { -#if HAVE_ZLIB - if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - inflateEnd(matvar->internal->z); - free(matvar->internal->z); - if ( matvar->class_type == MAT_C_SPARSE && NULL != matvar->internal->data ) { - mat_sparse_t *sparse; - sparse = (mat_sparse_t *)matvar->internal->data; - if ( sparse->ir != NULL ) - free(sparse->ir); - if ( sparse->jc != NULL ) - free(sparse->jc); - if ( matvar->isComplex && NULL != sparse->data ) { - ComplexFree((mat_complex_split_t *)sparse->data); - } else if ( sparse->data != NULL ) { - free(sparse->data); - } - free(sparse); - } else if ( matvar->isComplex && NULL != matvar->internal->data ) { - ComplexFree((mat_complex_split_t *)matvar->internal->data); - } else if ( NULL != matvar->internal->data ) { - free(matvar->internal->data); - } - } -#endif -#if HAVE_HDF5 - if ( -1 < matvar->internal->id ) { - switch ( H5Iget_type(matvar->internal->id) ) { - case H5I_GROUP: - H5Gclose(matvar->internal->id); - matvar->internal->id = -1; - break; - case H5I_DATASET: - H5Dclose(matvar->internal->id); - matvar->internal->id = -1; - break; - default: - break; - } - } - if ( 0 < matvar->internal->hdf5_ref ) { - switch ( H5Iget_type(matvar->internal->id) ) { - case H5I_GROUP: - H5Gclose(matvar->internal->id); - matvar->internal->hdf5_ref = -1; - break; - case H5I_DATASET: - H5Dclose(matvar->internal->id); - matvar->internal->hdf5_ref = -1; - break; - default: - break; - } - } - if ( NULL != matvar->internal->hdf5_name ) { - free(matvar->internal->hdf5_name); - matvar->internal->hdf5_name = NULL; - } -#endif - if ( NULL != matvar->internal->fieldnames && matvar->internal->num_fields > 0 ) { - size_t i; - for ( i = 0; i < matvar->internal->num_fields; i++ ) { - if ( NULL != matvar->internal->fieldnames[i] ) - free(matvar->internal->fieldnames[i]); - } - free(matvar->internal->fieldnames); - } - free(matvar->internal); - matvar->internal = NULL; - } - if ( NULL != matvar->name ) - free(matvar->name); - free(matvar); -} - -/** @brief Calculate a single subscript from a set of subscript values - * - * Calculates a single linear subscript (0-relative) given a 1-relative - * subscript for each dimension. The calculation uses the formula below where - * index is the linear index, s is an array of length RANK where each element - * is the subscript for the corresponding dimension, D is an array whose - * elements are the dimensions of the variable. - * \f[ - * index = \sum\limits_{k=0}^{RANK-1} [(s_k - 1) \prod\limits_{l=0}^{k} D_l ] - * \f] - * @ingroup MAT - * @param rank Rank of the variable - * @param dims Dimensions of the variable - * @param subs Array of dimension subscripts - * @return Single (linear) subscript - */ -int -Mat_CalcSingleSubscript(int rank, int *dims, int *subs) -{ - int index = 0, i, j, err = MATIO_E_NO_ERROR; - - for ( i = 0; i < rank; i++ ) { - int k = subs[i]; - if ( k > dims[i] ) { - err = MATIO_E_BAD_ARGUMENT; - Mat_Critical("Mat_CalcSingleSubscript: index out of bounds"); - break; - } else if ( k < 1 ) { - err = MATIO_E_BAD_ARGUMENT; - break; - } - k--; - for ( j = i; j--; ) - k *= dims[j]; - index += k; - } - if ( err ) - index = -1; - - return index; -} - -/** @brief Calculate a single subscript from a set of subscript values - * - * Calculates a single linear subscript (0-relative) given a 1-relative - * subscript for each dimension. The calculation uses the formula below where - * index is the linear index, s is an array of length RANK where each element - * is the subscript for the corresponding dimension, D is an array whose - * elements are the dimensions of the variable. - * \f[ - * index = \sum\limits_{k=0}^{RANK-1} [(s_k - 1) \prod\limits_{l=0}^{k} D_l ] - * \f] - * @ingroup MAT - * @param rank Rank of the variable - * @param dims Dimensions of the variable - * @param subs Array of dimension subscripts - * @param[out] index Single (linear) subscript - * @retval 0 on success - */ -int -Mat_CalcSingleSubscript2(int rank, size_t *dims, size_t *subs, size_t *index) -{ - int i, err = MATIO_E_NO_ERROR; - - for ( i = 0; i < rank; i++ ) { - int j; - size_t k = subs[i]; - if ( k > dims[i] ) { - err = MATIO_E_BAD_ARGUMENT; - Mat_Critical("Mat_CalcSingleSubscript2: index out of bounds"); - break; - } else if ( k < 1 ) { - err = MATIO_E_BAD_ARGUMENT; - break; - } - k--; - for ( j = i; j--; ) - k *= dims[j]; - *index += k; - } - - return err; -} - -/** @brief Calculate a set of subscript values from a single(linear) subscript - * - * Calculates 1-relative subscripts for each dimension given a 0-relative - * linear index. Subscripts are calculated as follows where s is the array - * of dimension subscripts, D is the array of dimensions, and index is the - * linear index. - * \f[ - * s_k = \lfloor\frac{1}{L} \prod\limits_{l = 0}^{k} D_l\rfloor + 1 - * \f] - * \f[ - * L = index - \sum\limits_{l = k}^{RANK - 1} s_k \prod\limits_{m = 0}^{k} D_m - * \f] - * @ingroup MAT - * @param rank Rank of the variable - * @param dims Dimensions of the variable - * @param index Linear index - * @return Array of dimension subscripts - */ -int * -Mat_CalcSubscripts(int rank, int *dims, int index) -{ - int i, j, *subs; - double l; - - subs = (int *)malloc(rank * sizeof(int)); - if ( NULL == subs ) { - return subs; - } - - l = index; - for ( i = rank; i--; ) { - int k = 1; - for ( j = i; j--; ) - k *= dims[j]; - subs[i] = (int)floor(l / (double)k); - l -= subs[i] * k; - subs[i]++; - } - - return subs; -} - -/** @brief Calculate a set of subscript values from a single(linear) subscript - * - * Calculates 1-relative subscripts for each dimension given a 0-relative - * linear index. Subscripts are calculated as follows where s is the array - * of dimension subscripts, D is the array of dimensions, and index is the - * linear index. - * \f[ - * s_k = \lfloor\frac{1}{L} \prod\limits_{l = 0}^{k} D_l\rfloor + 1 - * \f] - * \f[ - * L = index - \sum\limits_{l = k}^{RANK - 1} s_k \prod\limits_{m = 0}^{k} D_m - * \f] - * @ingroup MAT - * @param rank Rank of the variable - * @param dims Dimensions of the variable - * @param index Linear index - * @return Array of dimension subscripts - */ -size_t * -Mat_CalcSubscripts2(int rank, size_t *dims, size_t index) -{ - int i; - size_t *subs; - double l; - - subs = (size_t *)malloc(rank * sizeof(size_t)); - if ( NULL == subs ) { - return subs; - } - - l = (double)index; - for ( i = rank; i--; ) { - int j; - size_t k = 1; - for ( j = i; j--; ) - k *= dims[j]; - subs[i] = (size_t)floor(l / (double)k); - l -= subs[i] * k; - subs[i]++; - } - - return subs; -} - -/** @brief Calculates the size of a matlab variable in bytes - * - * @ingroup MAT - * @param matvar matlab variable - * @returns size of the variable in bytes, or 0 on error - */ -size_t -Mat_VarGetSize(matvar_t *matvar) -{ - int err; - size_t i; - size_t bytes = 0, overhead = 0, ptr = 0; - -#if defined(_WIN64) || (defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8)) || \ - (defined(SIZEOF_VOID_P) && (SIZEOF_VOID_P == 8)) - /* 112 bytes cell/struct overhead for 64-bit system */ - overhead = 112; - ptr = 8; -#elif defined(_WIN32) || (defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)) || \ - (defined(SIZEOF_VOID_P) && (SIZEOF_VOID_P == 4)) - /* 60 bytes cell/struct overhead for 32-bit system */ - overhead = 60; - ptr = 4; -#endif - - if ( matvar->class_type == MAT_C_STRUCT ) { - matvar_t **fields = (matvar_t **)matvar->data; - size_t field_name_length; - if ( NULL != fields ) { - size_t nelems_x_nfields = matvar->internal->num_fields; - err = Mat_MulDims(matvar, &nelems_x_nfields); - err |= Mul(&bytes, nelems_x_nfields, overhead); - if ( err ) - return 0; - - for ( i = 0; i < nelems_x_nfields; i++ ) { - if ( NULL != fields[i] ) { - if ( MAT_C_EMPTY != fields[i]->class_type ) { - err = Add(&bytes, bytes, Mat_VarGetSize(fields[i])); - if ( err ) - return 0; - } else { - bytes -= overhead; - bytes += ptr; - } - } - } - } - err = Mul(&field_name_length, 64 /* max field name length */, matvar->internal->num_fields); - err |= Add(&bytes, bytes, field_name_length); - if ( err ) - return 0; - } else if ( matvar->class_type == MAT_C_CELL ) { - matvar_t **cells = (matvar_t **)matvar->data; - if ( NULL != cells ) { - size_t nelems = matvar->nbytes / matvar->data_size; - err = Mul(&bytes, nelems, overhead); - if ( err ) - return 0; - - for ( i = 0; i < nelems; i++ ) { - if ( NULL != cells[i] ) { - if ( MAT_C_EMPTY != cells[i]->class_type ) { - err = Add(&bytes, bytes, Mat_VarGetSize(cells[i])); - if ( err ) - return 0; - } else { - bytes -= overhead; - bytes += ptr; - } - } - } - } - } else if ( matvar->class_type == MAT_C_SPARSE ) { - mat_sparse_t *sparse = (mat_sparse_t *)matvar->data; - if ( NULL != sparse ) { - size_t sparse_size = 0; - err = Mul(&bytes, sparse->ndata, Mat_SizeOf(matvar->data_type)); - if ( err ) - return 0; - - if ( matvar->isComplex ) { - err = Mul(&bytes, bytes, 2); - if ( err ) - return 0; - } - -#if defined(_WIN64) || (defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8)) || \ - (defined(SIZEOF_VOID_P) && (SIZEOF_VOID_P == 8)) - /* 8 byte integers for 64-bit system (as displayed in MATLAB (x64) whos) */ - err = Mul(&sparse_size, sparse->nir + sparse->njc, 8); -#elif defined(_WIN32) || (defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)) || \ - (defined(SIZEOF_VOID_P) && (SIZEOF_VOID_P == 4)) - /* 4 byte integers for 32-bit system (as defined by mat_sparse_t) */ - err = Mul(&sparse_size, sparse->nir + sparse->njc, 4); -#endif - err |= Add(&bytes, bytes, sparse_size); - if ( err ) - return 0; - - if ( sparse->ndata == 0 || sparse->nir == 0 || sparse->njc == 0 ) { - err = Add(&bytes, bytes, matvar->isLogical ? 1 : 8); - if ( err ) - return 0; - } - } - } else { - if ( matvar->rank > 0 ) { - bytes = Mat_SizeOfClass(matvar->class_type); - err = Mat_MulDims(matvar, &bytes); - if ( err ) - return 0; - - if ( matvar->isComplex ) { - err = Mul(&bytes, bytes, 2); - if ( err ) - return 0; - } - } - } - - return bytes; -} - -/** @brief Prints the variable information - * - * Prints to stdout the values of the @ref matvar_t structure - * @ingroup MAT - * @param matvar Pointer to the matvar_t structure - * @param printdata set to 1 if the Variables data should be printed, else 0 - */ -void -Mat_VarPrint(matvar_t *matvar, int printdata) -{ - size_t nelems = 0, i, j; - const char *class_type_desc[18] = {"Undefined", - "Cell Array", - "Structure", - "Object", - "Character Array", - "Sparse Array", - "Double Precision Array", - "Single Precision Array", - "8-bit, signed integer array", - "8-bit, unsigned integer array", - "16-bit, signed integer array", - "16-bit, unsigned integer array", - "32-bit, signed integer array", - "32-bit, unsigned integer array", - "64-bit, signed integer array", - "64-bit, unsigned integer array", - "Function", - "Opaque"}; - - if ( matvar == NULL ) - return; - if ( NULL != matvar->name ) - printf(" Name: %s\n", matvar->name); - printf(" Rank: %d\n", matvar->rank); - if ( matvar->rank <= 0 ) - return; - if ( NULL != matvar->dims ) { - int err; - nelems = 1; - err = Mat_MulDims(matvar, &nelems); - printf("Dimensions: %" SIZE_T_FMTSTR, matvar->dims[0]); - if ( MATIO_E_NO_ERROR == err ) { - int k; - for ( k = 1; k < matvar->rank; k++ ) { - printf(" x %" SIZE_T_FMTSTR, matvar->dims[k]); - } - } - printf("\n"); - } - printf("Class Type: %s", class_type_desc[matvar->class_type]); - if ( matvar->isComplex ) - printf(" (complex)"); - else if ( matvar->isLogical ) - printf(" (logical)"); - printf("\n"); - if ( matvar->data_type ) { - const char *data_type_desc[25] = {"Unknown", - "8-bit, signed integer", - "8-bit, unsigned integer", - "16-bit, signed integer", - "16-bit, unsigned integer", - "32-bit, signed integer", - "32-bit, unsigned integer", - "IEEE 754 single-precision", - "RESERVED", - "IEEE 754 double-precision", - "RESERVED", - "RESERVED", - "64-bit, signed integer", - "64-bit, unsigned integer", - "Matlab Array", - "Compressed Data", - "Unicode UTF-8 Encoded Character Data", - "Unicode UTF-16 Encoded Character Data", - "Unicode UTF-32 Encoded Character Data", - "RESERVED", - "String", - "Cell Array", - "Structure", - "Array", - "Function"}; - printf(" Data Type: %s\n", data_type_desc[matvar->data_type]); - } - - if ( MAT_C_STRUCT == matvar->class_type ) { - matvar_t **fields = (matvar_t **)matvar->data; - size_t nfields = matvar->internal->num_fields; - size_t nelems_x_nfields = 1; - int err = Mul(&nelems_x_nfields, nelems, nfields); - if ( MATIO_E_NO_ERROR == err && nelems_x_nfields > 0 ) { - printf("Fields[%" SIZE_T_FMTSTR "] {\n", nelems_x_nfields); - for ( i = 0; i < nelems_x_nfields; i++ ) { - if ( NULL == fields[i] ) { - printf(" Name: %s\n Rank: %d\n", - matvar->internal->fieldnames[i % nfields], 0); - } else { - Mat_VarPrint(fields[i], printdata); - } - } - printf("}\n"); - } else { - printf("Fields[%" SIZE_T_FMTSTR "] {\n", nfields); - for ( i = 0; i < nfields; i++ ) - printf(" Name: %s\n Rank: %d\n", matvar->internal->fieldnames[i], 0); - printf("}\n"); - } - return; - } else if ( matvar->data == NULL || matvar->data_size < 1 ) { - if ( printdata ) - printf("{\n}\n"); - return; - } else if ( MAT_C_CELL == matvar->class_type ) { - matvar_t **cells = (matvar_t **)matvar->data; - nelems = matvar->nbytes / matvar->data_size; - printf("{\n"); - for ( i = 0; i < nelems; i++ ) - Mat_VarPrint(cells[i], printdata); - printf("}\n"); - return; - } else if ( !printdata ) { - return; - } - - printf("{\n"); - - if ( matvar->rank > 2 ) { - printf("I can't print more than 2 dimensions\n"); - } else if ( matvar->rank == 1 && NULL != matvar->dims && matvar->dims[0] > 15 ) { - printf("I won't print more than 15 elements in a vector\n"); - } else if ( matvar->rank == 2 && NULL != matvar->dims ) { - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: -#endif -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: -#endif - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: { - size_t stride = Mat_SizeOf(matvar->data_type); - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)matvar->data; - char *rp = (char *)complex_data->Re; - char *ip = (char *)complex_data->Im; - for ( i = 0; i < matvar->dims[0] && i < 15; i++ ) { - for ( j = 0; j < matvar->dims[1] && j < 15; j++ ) { - size_t idx = matvar->dims[0] * j + i; - Mat_PrintNumber(matvar->data_type, rp + idx * stride); - printf(" + "); - Mat_PrintNumber(matvar->data_type, ip + idx * stride); - printf("i "); - } - if ( j < matvar->dims[1] ) - printf("..."); - printf("\n"); - } - if ( i < matvar->dims[0] ) - printf(".\n.\n.\n"); - } else { - char *data = (char *)matvar->data; - for ( i = 0; i < matvar->dims[0] && i < 15; i++ ) { - for ( j = 0; j < matvar->dims[1] && j < 15; j++ ) { - size_t idx = matvar->dims[0] * j + i; - Mat_PrintNumber(matvar->data_type, data + idx * stride); - printf(" "); - } - if ( j < matvar->dims[1] ) - printf("..."); - printf("\n"); - } - if ( i < matvar->dims[0] ) - printf(".\n.\n.\n"); - } - break; - } - case MAT_C_CHAR: { - switch ( matvar->data_type ) { - case MAT_T_UINT16: - case MAT_T_UTF16: { - const mat_uint16_t *data = (const mat_uint16_t *)matvar->data; - for ( i = 0; i < matvar->dims[0]; i++ ) { - for ( j = 0; j < matvar->dims[1]; j++ ) { - const mat_uint16_t c = data[j * matvar->dims[0] + i]; -#if defined VARPRINT_UTF16 - printf("%c%c", c & 0xFF, (c >> 8) & 0xFF); -#elif defined VARPRINT_UTF16_DECIMAL - Mat_PrintNumber(MAT_T_UINT16, &c); - printf(" "); -#else - /* Convert to UTF-8 */ - if ( c <= 0x7F ) { - printf("%c", c); - } else if ( c <= 0x7FF ) { - printf("%c%c", 0xC0 | (c >> 6), 0x80 | (c & 0x3F)); - } else /* if (c <= 0xFFFF) */ { - printf("%c%c%c", 0xE0 | (c >> 12), 0x80 | ((c >> 6) & 0x3F), - 0x80 | (c & 0x3F)); - } -#endif - } - printf("\n"); - } - break; - } - case MAT_T_UTF8: { - const mat_uint8_t *data = (const mat_uint8_t *)matvar->data; - size_t k = 0; - size_t *idxOffset; - if ( matvar->nbytes == 0 ) { - break; - } - idxOffset = (size_t *)calloc(nelems, sizeof(size_t)); - if ( idxOffset == NULL ) { - break; - } - for ( i = 0; i < matvar->dims[0]; i++ ) { - for ( j = 0; j < matvar->dims[1]; j++ ) { - mat_uint8_t c; - if ( k >= matvar->nbytes ) { - break; - } - idxOffset[i * matvar->dims[1] + j] = k; - c = data[k]; - if ( c <= 0x7F ) { - } else if ( (c & 0xE0) == 0xC0 && k + 1 < matvar->nbytes ) { - k = k + 1; - } else if ( (c & 0xF0) == 0xE0 && k + 2 < matvar->nbytes ) { - k = k + 2; - } else if ( (c & 0xF8) == 0xF0 && k + 3 < matvar->nbytes ) { - k = k + 3; - } - ++k; - } - } - for ( i = 0; i < matvar->dims[0]; i++ ) { - for ( j = 0; j < matvar->dims[1]; j++ ) { - mat_uint8_t c; - k = idxOffset[j * matvar->dims[0] + i]; - c = data[k]; - if ( c <= 0x7F ) { - printf("%c", c); - } else if ( (c & 0xE0) == 0xC0 ) { - printf("%c%c", c, data[k + 1]); - } else if ( (c & 0xF0) == 0xE0 ) { - printf("%c%c%c", c, data[k + 1], data[k + 2]); - } else if ( (c & 0xF8) == 0xF0 ) { - printf("%c%c%c%c", c, data[k + 1], data[k + 2], data[k + 3]); - } - } - printf("\n"); - } - free(idxOffset); - break; - } - default: { - const char *data = (const char *)matvar->data; - for ( i = 0; i < matvar->dims[0]; i++ ) { - for ( j = 0; j < matvar->dims[1]; j++ ) - printf("%c", data[j * matvar->dims[0] + i]); - printf("\n"); - } - break; - } - } - break; - } - case MAT_C_SPARSE: { - mat_sparse_t *sparse; - size_t stride = Mat_SizeOf(matvar->data_type); -#if !defined(EXTENDED_SPARSE) - if ( MAT_T_DOUBLE != matvar->data_type ) - break; -#endif - sparse = (mat_sparse_t *)matvar->data; - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)sparse->data; - char *re = (char *)complex_data->Re; - char *im = (char *)complex_data->Im; - for ( i = 0; i < (size_t)sparse->njc - 1; i++ ) { - for ( j = sparse->jc[i]; - j < (size_t)sparse->jc[i + 1] && j < (size_t)sparse->ndata; j++ ) { - printf(" (%u,%" SIZE_T_FMTSTR ") ", sparse->ir[j] + 1, i + 1); - Mat_PrintNumber(matvar->data_type, re + j * stride); - printf(" + "); - Mat_PrintNumber(matvar->data_type, im + j * stride); - printf("i\n"); - } - } - } else { - char *data = (char *)sparse->data; - for ( i = 0; i < (size_t)sparse->njc - 1; i++ ) { - for ( j = sparse->jc[i]; - j < (size_t)sparse->jc[i + 1] && j < (size_t)sparse->ndata; j++ ) { - printf(" (%u,%" SIZE_T_FMTSTR ") ", sparse->ir[j] + 1, i + 1); - Mat_PrintNumber(matvar->data_type, data + j * stride); - printf("\n"); - } - } - } - break; - } /* case MAT_C_SPARSE: */ - default: - break; - } /* switch( matvar->class_type ) */ - } - - printf("}\n"); - - return; -} - -/** @brief Reads MAT variable data from a file - * - * Reads data from a MAT variable. The variable must have been read by - * Mat_VarReadInfo. - * @ingroup MAT - * @param mat MAT file to read data from - * @param matvar MAT variable information - * @param data pointer to store data in (must be pre-allocated) - * @param start array of starting indices - * @param stride stride of data - * @param edge array specifying the number to read in each direction - * @retval 0 on success - */ -int -Mat_VarReadData(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, int *edge) -{ - int err = MATIO_E_NO_ERROR; - - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: - break; - default: - return MATIO_E_OPERATION_NOT_SUPPORTED; - } - - switch ( mat->version ) { - case MAT_FT_MAT5: - err = Mat_VarReadData5(mat, matvar, data, start, stride, edge); - break; - case MAT_FT_MAT73: -#if HAVE_HDF5 - err = Mat_VarReadData73(mat, matvar, data, start, stride, edge); -#else - err = MATIO_E_OPERATION_NOT_SUPPORTED; -#endif - break; - case MAT_FT_MAT4: - err = Mat_VarReadData4(mat, matvar, data, start, stride, edge); - break; - default: - err = MATIO_E_FAIL_TO_IDENTIFY; - break; - } - - return err; -} - -/** @brief Reads all the data for a matlab variable - * - * Allocates memory and reads the data for a given matlab variable. - * @ingroup MAT - * @param mat Matlab MAT file structure pointer - * @param matvar Variable whose data is to be read - * @returns non-zero on error - */ -int -Mat_VarReadDataAll(mat_t *mat, matvar_t *matvar) -{ - int err = MATIO_E_NO_ERROR; - - if ( mat == NULL || matvar == NULL ) - err = MATIO_E_BAD_ARGUMENT; - else - err = ReadData(mat, matvar); - - return err; -} - -/** @brief Reads a subset of a MAT variable using a 1-D indexing - * - * Reads data from a MAT variable using a linear (1-D) indexing mode. The - * variable must have been read by Mat_VarReadInfo. - * @ingroup MAT - * @param mat MAT file to read data from - * @param matvar MAT variable information - * @param data pointer to store data in (must be pre-allocated) - * @param start starting index - * @param stride stride of data - * @param edge number of elements to read - * @retval 0 on success - */ -int -Mat_VarReadDataLinear(mat_t *mat, matvar_t *matvar, void *data, int start, int stride, int edge) -{ - int err = MATIO_E_NO_ERROR; - - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: - break; - default: - return MATIO_E_OPERATION_NOT_SUPPORTED; - } - - switch ( mat->version ) { - case MAT_FT_MAT5: - err = Mat_VarReadDataLinear5(mat, matvar, data, start, stride, edge); - break; - case MAT_FT_MAT73: -#if HAVE_HDF5 - err = Mat_VarReadDataLinear73(mat, matvar, data, start, stride, edge); -#else - err = MATIO_E_OPERATION_NOT_SUPPORTED; -#endif - break; - case MAT_FT_MAT4: - err = Mat_VarReadDataLinear4(mat, matvar, data, start, stride, edge); - break; - default: - err = MATIO_E_FAIL_TO_IDENTIFY; - break; - } - - return err; -} - -/** @brief Reads the information of the next variable in a MAT file - * - * Reads the next variable's information (class,flags-complex/global/logical, - * rank,dimensions, name, etc) from the Matlab MAT file. After reading, the MAT - * file is positioned past the current variable. - * @ingroup MAT - * @param mat Pointer to the MAT file - * @return Pointer to the @ref matvar_t structure containing the MAT - * variable information - */ -matvar_t * -Mat_VarReadNextInfo(mat_t *mat) -{ - matvar_t *matvar; - if ( mat == NULL ) - return NULL; - - switch ( mat->version ) { - case MAT_FT_MAT5: - matvar = Mat_VarReadNextInfo5(mat); - break; - case MAT_FT_MAT73: -#if HAVE_HDF5 - matvar = Mat_VarReadNextInfo73(mat); -#else - matvar = NULL; -#endif - break; - case MAT_FT_MAT4: - matvar = Mat_VarReadNextInfo4(mat); - break; - default: - matvar = NULL; - break; - } - - return matvar; -} - -/** @brief Reads the information of a variable with the given name from a MAT file - * - * Reads the named variable (or the next variable if name is NULL) information - * (class,flags-complex/global/logical,rank,dimensions,and name) from the - * Matlab MAT file - * @ingroup MAT - * @param mat Pointer to the MAT file - * @param name Name of the variable to read - * @return Pointer to the @ref matvar_t structure containing the MAT - * variable information - */ -matvar_t * -Mat_VarReadInfo(mat_t *mat, const char *name) -{ - matvar_t *matvar = NULL; - - if ( mat == NULL || name == NULL ) - return NULL; - - if ( mat->version == MAT_FT_MAT73 ) { - size_t fpos = mat->next_index; - mat->next_index = 0; - while ( NULL == matvar && mat->next_index < mat->num_datasets ) { - matvar = Mat_VarReadNextInfo(mat); - if ( matvar != NULL ) { - if ( matvar->name == NULL || 0 != strcmp(matvar->name, name) ) { - Mat_VarFree(matvar); - matvar = NULL; - } - } else { - Mat_Critical("An error occurred in reading the MAT file"); - break; - } - } - mat->next_index = fpos; - } else { - long fpos = ftell((FILE *)mat->fp); - if ( fpos != -1L ) { - (void)fseek((FILE *)mat->fp, mat->bof, SEEK_SET); - do { - matvar = Mat_VarReadNextInfo(mat); - if ( matvar != NULL ) { - if ( matvar->name == NULL || 0 != strcmp(matvar->name, name) ) { - Mat_VarFree(matvar); - matvar = NULL; - } - } else if ( !IsEndOfFile((FILE *)mat->fp, NULL) ) { - Mat_Critical("An error occurred in reading the MAT file"); - break; - } - } while ( NULL == matvar && !IsEndOfFile((FILE *)mat->fp, NULL) ); - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - } else { - Mat_Critical("Couldn't determine file position"); - } - } - - return matvar; -} - -/** @brief Reads the variable with the given name from a MAT file - * - * Reads the next variable in the Matlab MAT file - * @ingroup MAT - * @param mat Pointer to the MAT file - * @param name Name of the variable to read - * @return Pointer to the @ref matvar_t structure containing the MAT - * variable information - */ -matvar_t * -Mat_VarRead(mat_t *mat, const char *name) -{ - matvar_t *matvar = NULL; - - if ( mat == NULL || name == NULL ) - return NULL; - - if ( MAT_FT_MAT73 != mat->version ) { - long fpos = ftell((FILE *)mat->fp); - if ( fpos == -1L ) { - Mat_Critical("Couldn't determine file position"); - return NULL; - } - matvar = Mat_VarReadInfo(mat, name); - if ( matvar ) { - const int err = ReadData(mat, matvar); - if ( err ) { - Mat_VarFree(matvar); - matvar = NULL; - } - } - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - } else { - size_t fpos = mat->next_index; - mat->next_index = 0; - matvar = Mat_VarReadInfo(mat, name); - if ( matvar ) { - const int err = ReadData(mat, matvar); - if ( err ) { - Mat_VarFree(matvar); - matvar = NULL; - } - } - mat->next_index = fpos; - } - - return matvar; -} - -/** @brief Reads the next variable in a MAT file - * - * Reads the next variable in the Matlab MAT file - * @ingroup MAT - * @param mat Pointer to the MAT file - * @return Pointer to the @ref matvar_t structure containing the MAT - * variable information - */ -matvar_t * -Mat_VarReadNext(mat_t *mat) -{ - long fpos; - matvar_t *matvar; - - if ( mat->version != MAT_FT_MAT73 ) { - if ( IsEndOfFile((FILE *)mat->fp, &fpos) ) - return NULL; - if ( fpos == -1L ) { - return NULL; - } - } - matvar = Mat_VarReadNextInfo(mat); - if ( matvar ) { - const int err = ReadData(mat, matvar); - if ( err ) { - Mat_VarFree(matvar); - matvar = NULL; - } - } else if ( mat->version != MAT_FT_MAT73 ) { - /* Reset the file position */ - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - } - - return matvar; -} - -/** @brief Writes the given MAT variable to a MAT file - * - * Writes the MAT variable information stored in matvar to the given MAT file. - * The variable will be written to the end of the file. - * @ingroup MAT - * @param mat MAT file to write to - * @param matvar MAT variable information to write - * @retval 1 - * @deprecated - * @see Mat_VarWrite/Mat_VarWriteAppend - */ -int -Mat_VarWriteInfo(mat_t *mat, matvar_t *matvar) -{ - Mat_Critical( - "Mat_VarWriteInfo/Mat_VarWriteData is not supported. " - "Use %s instead!", - mat->version == MAT_FT_MAT73 ? "Mat_VarWrite/Mat_VarWriteAppend" : "Mat_VarWrite"); - return MATIO_E_OPERATION_NOT_SUPPORTED; -} - -/** @brief Writes the given data to the MAT variable - * - * Writes data to a MAT variable. The variable must have previously been - * written with Mat_VarWriteInfo. - * @ingroup MAT - * @param mat MAT file to write to - * @param matvar MAT variable information to write - * @param data pointer to the data to write - * @param start array of starting indices - * @param stride stride of data - * @param edge array specifying the number to read in each direction - * @retval 1 - * @deprecated - * @see Mat_VarWrite/Mat_VarWriteAppend - */ -int -Mat_VarWriteData(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, int *edge) -{ - Mat_Critical( - "Mat_VarWriteInfo/Mat_VarWriteData is not supported. " - "Use %s instead!", - mat->version == MAT_FT_MAT73 ? "Mat_VarWrite/Mat_VarWriteAppend" : "Mat_VarWrite"); - return MATIO_E_OPERATION_NOT_SUPPORTED; -} - -/** @brief Writes the given MAT variable to a MAT file - * - * Writes the MAT variable information stored in matvar to the given MAT file. - * The variable will be written to the end of the file. - * @ingroup MAT - * @param mat MAT file to write to - * @param matvar MAT variable information to write - * @param compress Whether or not to compress the data - * (Only valid for version 5 and 7.3 MAT files and variables with - numeric data) - * @retval 0 on success - */ -int -Mat_VarWrite(mat_t *mat, matvar_t *matvar, enum matio_compression compress) -{ - int err; - - if ( NULL == mat || NULL == matvar ) - return MATIO_E_BAD_ARGUMENT; - - if ( NULL == mat->dir ) { - size_t n = 0; - (void)Mat_GetDir(mat, &n); - } - - { - /* Error if MAT variable already exists in MAT file */ - size_t i; - for ( i = 0; i < mat->num_datasets; i++ ) { - if ( NULL != mat->dir[i] && 0 == strcmp(mat->dir[i], matvar->name) ) { - Mat_Critical("Variable %s already exists.", matvar->name); - return MATIO_E_OUTPUT_BAD_DATA; - } - } - } - - if ( mat->version == MAT_FT_MAT5 ) - err = Mat_VarWrite5(mat, matvar, compress); - else if ( mat->version == MAT_FT_MAT73 ) -#if HAVE_HDF5 - err = Mat_VarWrite73(mat, matvar, compress); -#else - err = MATIO_E_OPERATION_NOT_SUPPORTED; -#endif - else if ( mat->version == MAT_FT_MAT4 ) - err = Mat_VarWrite4(mat, matvar); - else - err = MATIO_E_FAIL_TO_IDENTIFY; - - if ( err == MATIO_E_NO_ERROR ) { - /* Update directory */ - char **dir; - if ( NULL == mat->dir ) { - dir = (char **)malloc(sizeof(char *)); - } else { - dir = (char **)realloc(mat->dir, (mat->num_datasets + 1) * (sizeof(char *))); - } - if ( NULL != dir ) { - mat->dir = dir; - if ( NULL != matvar->name ) { - mat->dir[mat->num_datasets++] = Mat_strdup(matvar->name); - } else { - mat->dir[mat->num_datasets++] = NULL; - } - } else { - err = MATIO_E_OUT_OF_MEMORY; - Mat_Critical("Couldn't allocate memory for the directory"); - } - } - - return err; -} - -/** @brief Writes/appends the given MAT variable to a version 7.3 MAT file - * - * Writes the numeric data of the MAT variable stored in matvar to the given - * MAT file. The variable will be written to the end of the file if it does - * not yet exist or appended to the existing variable. - * @ingroup MAT - * @param mat MAT file to write to - * @param matvar MAT variable information to write - * @param compress Whether or not to compress the data - * (Only valid for version 7.3 MAT files and variables with numeric data) - * @param dim dimension to append data - * (Only valid for version 7.3 MAT files and variables with numeric data) - * @retval 0 on success - */ -int -Mat_VarWriteAppend(mat_t *mat, matvar_t *matvar, enum matio_compression compress, int dim) -{ - int err; - - if ( NULL == mat || NULL == matvar ) - return MATIO_E_BAD_ARGUMENT; - - if ( NULL == mat->dir ) { - size_t n = 0; - (void)Mat_GetDir(mat, &n); - } - - if ( mat->version == MAT_FT_MAT73 ) { -#if HAVE_HDF5 - int append = 0; - { - /* Check if MAT variable already exists in MAT file */ - size_t i; - for ( i = 0; i < mat->num_datasets; i++ ) { - if ( NULL != mat->dir[i] && 0 == strcmp(mat->dir[i], matvar->name) ) { - append = 1; - break; - } - } - } - err = Mat_VarWriteAppend73(mat, matvar, compress, dim); - if ( err == MATIO_E_NO_ERROR && 0 == append ) { - /* Update directory */ - char **dir; - if ( NULL == mat->dir ) { - dir = (char **)malloc(sizeof(char *)); - } else { - dir = (char **)realloc(mat->dir, (mat->num_datasets + 1) * (sizeof(char *))); - } - if ( NULL != dir ) { - mat->dir = dir; - if ( NULL != matvar->name ) { - mat->dir[mat->num_datasets++] = Mat_strdup(matvar->name); - } else { - mat->dir[mat->num_datasets++] = NULL; - } - } else { - err = MATIO_E_OUT_OF_MEMORY; - Mat_Critical("Couldn't allocate memory for the directory"); - } - } -#else - err = MATIO_E_OPERATION_NOT_SUPPORTED; -#endif - } else if ( mat->version == MAT_FT_MAT4 || mat->version == MAT_FT_MAT5 ) { - err = MATIO_E_OPERATION_NOT_SUPPORTED; - } else { - err = MATIO_E_FAIL_TO_IDENTIFY; - } - - return err; -} - -/* ------------------------------- - * ---------- mat4.c - * ------------------------------- - */ -/** @file mat4.c - * Matlab MAT version 4 file functions - * @ingroup MAT - */ - -/** @if mat_devman - * @brief Creates a new Matlab MAT version 4 file - * - * Tries to create a new Matlab MAT file with the given name. - * @ingroup MAT - * @param matname Name of MAT file to create - * @return A pointer to the MAT file or NULL if it failed. This is not a - * simple FILE * and should not be used as one. - * @endif - */ -static mat_t * -Mat_Create4(const char *matname) -{ - FILE *fp = NULL; - mat_t *mat = NULL; - -#if defined(_WIN32) && defined(_MSC_VER) - wchar_t *wname = utf82u(matname); - if ( NULL != wname ) { - fp = _wfopen(wname, L"w+b"); - free(wname); - } -#else - fp = fopen(matname, "w+b"); -#endif - if ( !fp ) - return NULL; - - mat = (mat_t *)malloc(sizeof(*mat)); - if ( NULL == mat ) { - fclose(fp); - Mat_Critical("Couldn't allocate memory for the MAT file"); - return NULL; - } - - mat->fp = fp; - mat->header = NULL; - mat->subsys_offset = NULL; - mat->filename = Mat_strdup(matname); - mat->version = MAT_FT_MAT4; - mat->byteswap = 0; - mat->mode = 0; - mat->bof = 0; - mat->next_index = 0; - mat->num_datasets = 0; -#if HAVE_HDF5 - mat->refs_id = -1; -#endif - mat->dir = NULL; - - Mat_Rewind(mat); - - return mat; -} - -/** @if mat_devman - * @brief Writes a matlab variable to a version 4 matlab file - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @retval 0 on success - * @endif - */ -static int -Mat_VarWrite4(mat_t *mat, matvar_t *matvar) -{ - typedef struct - { - mat_int32_t type; - mat_int32_t mrows; - mat_int32_t ncols; - mat_int32_t imagf; - mat_int32_t namelen; - } Fmatrix; - - mat_uint32_t i; - Fmatrix x; - - if ( NULL == mat || NULL == matvar ) - return MATIO_E_BAD_ARGUMENT; - if ( NULL == matvar->name || matvar->rank != 2 ) - return MATIO_E_OUTPUT_BAD_DATA; - - switch ( matvar->data_type ) { - case MAT_T_DOUBLE: - x.type = 0; - break; - case MAT_T_SINGLE: - x.type = 10; - break; - case MAT_T_INT32: - x.type = 20; - break; - case MAT_T_INT16: - x.type = 30; - break; - case MAT_T_UINT16: - x.type = 40; - break; - case MAT_T_UINT8: - x.type = 50; - break; - default: - return MATIO_E_OUTPUT_BAD_DATA; - } - -#if defined(__GLIBC__) -#if ( __BYTE_ORDER == __LITTLE_ENDIAN ) -#elif (__BYTE_ORDER == __BIG_ENDIAN) - x.type += 1000; -#else - return MATIO_E_OPERATION_NOT_SUPPORTED; -#endif -#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) - x.type += 1000; -#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) -#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || \ - defined(__ppc__) || defined(__hpux) || defined(_MIPSEB) || defined(_POWER) || \ - defined(__s390__) - x.type += 1000; -#elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || \ - defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || \ - defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_X64) || defined(__bfin__) -#else - return MATIO_E_OPERATION_NOT_SUPPORTED; -#endif - - x.namelen = (mat_int32_t)strlen(matvar->name) + 1; - - /* FIXME: SEEK_END is not Guaranteed by the C standard */ - (void)fseek((FILE *)mat->fp, 0, SEEK_END); /* Always write at end of file */ - - switch ( matvar->class_type ) { - case MAT_C_CHAR: - x.type++; - /* Fall through */ - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_UINT8: { - size_t nelems = 1; - int err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - x.mrows = (mat_int32_t)matvar->dims[0]; - x.ncols = (mat_int32_t)matvar->dims[1]; - x.imagf = matvar->isComplex ? 1 : 0; - fwrite(&x, sizeof(Fmatrix), 1, (FILE *)mat->fp); - fwrite(matvar->name, sizeof(char), x.namelen, (FILE *)mat->fp); - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data; - - complex_data = (mat_complex_split_t *)matvar->data; - fwrite(complex_data->Re, matvar->data_size, nelems, (FILE *)mat->fp); - fwrite(complex_data->Im, matvar->data_size, nelems, (FILE *)mat->fp); - } else { - fwrite(matvar->data, matvar->data_size, nelems, (FILE *)mat->fp); - } - break; - } - case MAT_C_SPARSE: { - mat_sparse_t *sparse; - double tmp; - mat_uint32_t j; - size_t stride = Mat_SizeOf(matvar->data_type); -#if !defined(EXTENDED_SPARSE) - if ( MAT_T_DOUBLE != matvar->data_type ) - break; -#endif - - sparse = (mat_sparse_t *)matvar->data; - x.type += 2; - x.mrows = sparse->njc > 0 ? sparse->jc[sparse->njc - 1] + 1 : 1; - x.ncols = matvar->isComplex ? 4 : 3; - x.imagf = 0; - - fwrite(&x, sizeof(Fmatrix), 1, (FILE *)mat->fp); - fwrite(matvar->name, sizeof(char), x.namelen, (FILE *)mat->fp); - - for ( i = 0; i < sparse->njc - 1; i++ ) { - for ( j = sparse->jc[i]; j < sparse->jc[i + 1] && j < sparse->ndata; j++ ) { - tmp = sparse->ir[j] + 1; - fwrite(&tmp, sizeof(double), 1, (FILE *)mat->fp); - } - } - tmp = (double)matvar->dims[0]; - fwrite(&tmp, sizeof(double), 1, (FILE *)mat->fp); - for ( i = 0; i < sparse->njc - 1; i++ ) { - for ( j = sparse->jc[i]; j < sparse->jc[i + 1] && j < sparse->ndata; j++ ) { - tmp = i + 1; - fwrite(&tmp, sizeof(double), 1, (FILE *)mat->fp); - } - } - tmp = (double)matvar->dims[1]; - fwrite(&tmp, sizeof(double), 1, (FILE *)mat->fp); - tmp = 0.; - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data; - char *re, *im; - - complex_data = (mat_complex_split_t *)sparse->data; - re = (char *)complex_data->Re; - im = (char *)complex_data->Im; - for ( i = 0; i < sparse->njc - 1; i++ ) { - for ( j = sparse->jc[i]; j < sparse->jc[i + 1] && j < sparse->ndata; j++ ) { - fwrite(re + j * stride, stride, 1, (FILE *)mat->fp); - } - } - fwrite(&tmp, stride, 1, (FILE *)mat->fp); - for ( i = 0; i < sparse->njc - 1; i++ ) { - for ( j = sparse->jc[i]; j < sparse->jc[i + 1] && j < sparse->ndata; j++ ) { - fwrite(im + j * stride, stride, 1, (FILE *)mat->fp); - } - } - } else { - char *data = (char *)sparse->data; - for ( i = 0; i < sparse->njc - 1; i++ ) { - for ( j = sparse->jc[i]; j < sparse->jc[i + 1] && j < sparse->ndata; j++ ) { - fwrite(data + j * stride, stride, 1, (FILE *)mat->fp); - } - } - } - fwrite(&tmp, stride, 1, (FILE *)mat->fp); - break; - } - default: - break; - } - - return MATIO_E_NO_ERROR; -} - -/** @if mat_devman - * @brief Reads the data of a version 4 MAT file variable - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar MAT variable pointer to read the data - * @retval 0 on success - * @endif - */ -static int -Mat_VarRead4(mat_t *mat, matvar_t *matvar) -{ - int err; - size_t nelems = 1; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - matvar->data_size = sizeof(double); - err = Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = ComplexMalloc(matvar->nbytes); - if ( NULL != complex_data ) { - size_t readcount; - readcount = - ReadDoubleData(mat, (double *)complex_data->Re, matvar->data_type, nelems); - err = readcount != nelems; - readcount = - ReadDoubleData(mat, (double *)complex_data->Im, matvar->data_type, nelems); - err |= readcount != nelems; - if ( 0 == err ) { - matvar->data = complex_data; - } else { - ComplexFree(complex_data); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - } else { - Mat_Critical("Couldn't allocate memory for the complex data"); - return MATIO_E_OUT_OF_MEMORY; - } - } else { - matvar->data = malloc(matvar->nbytes); - if ( NULL != matvar->data ) { - const size_t readcount = - ReadDoubleData(mat, (double *)matvar->data, matvar->data_type, nelems); - if ( readcount != nelems ) { - free(matvar->data); - matvar->data = NULL; - return MATIO_E_FILE_FORMAT_VIOLATION; - } - } else { - Mat_Critical("Couldn't allocate memory for the data"); - return MATIO_E_OUT_OF_MEMORY; - } - } - /* Update data type to match format of matvar->data */ - matvar->data_type = MAT_T_DOUBLE; - break; - case MAT_C_CHAR: - matvar->data_size = 1; - matvar->nbytes = nelems; - matvar->data = malloc(matvar->nbytes); - if ( NULL != matvar->data ) { - const size_t readcount = - ReadUInt8Data(mat, (mat_uint8_t *)matvar->data, matvar->data_type, nelems); - if ( readcount != nelems ) { - free(matvar->data); - matvar->data = NULL; - return MATIO_E_FILE_FORMAT_VIOLATION; - } - } else { - Mat_Critical("Couldn't allocate memory for the data"); - return MATIO_E_OUT_OF_MEMORY; - } - matvar->data_type = MAT_T_UINT8; - break; - case MAT_C_SPARSE: - matvar->data_size = sizeof(mat_sparse_t); - matvar->data = calloc(1, matvar->data_size); - if ( NULL != matvar->data ) { - double tmp; - mat_uint32_t i; - mat_sparse_t *sparse; - long fpos; - enum matio_types data_type = MAT_T_DOUBLE; - size_t readcount; - - /* matvar->dims[1] either is 3 for real or 4 for complex sparse */ - matvar->isComplex = matvar->dims[1] == 4 ? 1 : 0; - if ( matvar->dims[0] < 2 ) { - return MATIO_E_FILE_FORMAT_VIOLATION; - } - sparse = (mat_sparse_t *)matvar->data; - sparse->nir = matvar->dims[0] - 1; - sparse->nzmax = sparse->nir; - err = Mul(&readcount, sparse->nir, sizeof(mat_uint32_t)); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - sparse->ir = (mat_uint32_t *)malloc(readcount); - if ( sparse->ir != NULL ) { - readcount = ReadUInt32Data(mat, sparse->ir, data_type, sparse->nir); - if ( readcount != sparse->nir ) { - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - return MATIO_E_FILE_FORMAT_VIOLATION; - } - for ( i = 0; i < sparse->nir; i++ ) { - if ( 0 == sparse->ir[i] ) { - err = MATIO_E_FILE_FORMAT_VIOLATION; - break; - } - sparse->ir[i] = sparse->ir[i] - 1; - } - if ( err ) { - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - return err; - } - } else { - free(matvar->data); - matvar->data = NULL; - Mat_Critical("Couldn't allocate memory for the sparse row array"); - return MATIO_E_OUT_OF_MEMORY; - } - readcount = ReadDoubleData(mat, &tmp, data_type, 1); - if ( readcount != 1 || tmp > UINT_MAX - 1 || tmp < 0 ) { - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical("Invalid row dimension for sparse matrix"); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - matvar->dims[0] = (size_t)tmp; - - fpos = ftell((FILE *)mat->fp); - if ( fpos == -1L ) { - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical("Couldn't determine file position"); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - (void)fseek((FILE *)mat->fp, sparse->nir * Mat_SizeOf(data_type), SEEK_CUR); - readcount = ReadDoubleData(mat, &tmp, data_type, 1); - if ( readcount != 1 || tmp > UINT_MAX - 1 || tmp < 0 ) { - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical("Invalid column dimension for sparse matrix"); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - matvar->dims[1] = (size_t)tmp; - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - if ( matvar->dims[1] > UINT_MAX - 1 ) { - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical("Invalid column dimension for sparse matrix"); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - sparse->njc = (mat_uint32_t)matvar->dims[1] + 1; - err = Mul(&readcount, sparse->njc, sizeof(mat_uint32_t)); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - sparse->jc = (mat_uint32_t *)malloc(readcount); - if ( sparse->jc != NULL ) { - mat_uint32_t *jc; - err = Mul(&readcount, sparse->nir, sizeof(mat_uint32_t)); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - jc = (mat_uint32_t *)malloc(readcount); - if ( jc != NULL ) { - mat_uint32_t j = 0; - sparse->jc[0] = 0; - readcount = ReadUInt32Data(mat, jc, data_type, sparse->nir); - if ( readcount != sparse->nir ) { - free(jc); - free(sparse->jc); - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - return MATIO_E_FILE_FORMAT_VIOLATION; - } - for ( i = 1; i < sparse->njc - 1; i++ ) { - while ( j < sparse->nir && jc[j] <= i ) - j++; - sparse->jc[i] = j; - } - free(jc); - /* terminating nnz */ - sparse->jc[sparse->njc - 1] = sparse->nir; - } else { - free(sparse->jc); - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical("Couldn't allocate memory for the sparse index array"); - return MATIO_E_OUT_OF_MEMORY; - } - } else { - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical("Couldn't allocate memory for the sparse index array"); - return MATIO_E_OUT_OF_MEMORY; - } - readcount = ReadDoubleData(mat, &tmp, data_type, 1); - if ( readcount != 1 ) { - free(sparse->jc); - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - return MATIO_E_FILE_FORMAT_VIOLATION; - } - sparse->ndata = sparse->nir; - data_type = matvar->data_type; - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = - ComplexMalloc(sparse->ndata * Mat_SizeOf(data_type)); - if ( NULL != complex_data ) { - sparse->data = complex_data; -#if defined(EXTENDED_SPARSE) - switch ( data_type ) { - case MAT_T_DOUBLE: - readcount = ReadDoubleData(mat, (double *)complex_data->Re, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadDoubleData(mat, &tmp, data_type, 1); - err |= readcount != 1; - readcount = ReadDoubleData(mat, (double *)complex_data->Im, - data_type, sparse->ndata); - err |= readcount != sparse->ndata; - readcount = ReadDoubleData(mat, &tmp, data_type, 1); - err |= readcount != 1; - break; - case MAT_T_SINGLE: { - float tmp2; - readcount = ReadSingleData(mat, (float *)complex_data->Re, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadSingleData(mat, &tmp2, data_type, 1); - err |= readcount != 1; - readcount = ReadSingleData(mat, (float *)complex_data->Im, - data_type, sparse->ndata); - err |= readcount != sparse->ndata; - readcount = ReadSingleData(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - case MAT_T_INT32: { - mat_int32_t tmp2; - readcount = ReadInt32Data(mat, (mat_int32_t *)complex_data->Re, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadInt32Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - readcount = ReadInt32Data(mat, (mat_int32_t *)complex_data->Im, - data_type, sparse->ndata); - err |= readcount != sparse->ndata; - readcount = ReadInt32Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - case MAT_T_INT16: { - mat_int16_t tmp2; - readcount = ReadInt16Data(mat, (mat_int16_t *)complex_data->Re, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadInt16Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - readcount = ReadInt16Data(mat, (mat_int16_t *)complex_data->Im, - data_type, sparse->ndata); - err |= readcount != sparse->ndata; - readcount = ReadInt16Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - case MAT_T_UINT16: { - mat_uint16_t tmp2; - readcount = ReadUInt16Data(mat, (mat_uint16_t *)complex_data->Re, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadUInt16Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - readcount = ReadUInt16Data(mat, (mat_uint16_t *)complex_data->Im, - data_type, sparse->ndata); - err |= readcount != sparse->ndata; - readcount = ReadUInt16Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - case MAT_T_UINT8: { - mat_uint8_t tmp2; - readcount = ReadUInt8Data(mat, (mat_uint8_t *)complex_data->Re, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadUInt8Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - readcount = ReadUInt8Data(mat, (mat_uint8_t *)complex_data->Im, - data_type, sparse->ndata); - err |= readcount != sparse->ndata; - readcount = ReadUInt8Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - default: - ComplexFree(complex_data); - free(sparse->jc); - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical( - "Mat_VarRead4: %d is not a supported data type for " - "extended sparse", - data_type); - return MATIO_E_FILE_FORMAT_VIOLATION; - } -#else - readcount = ReadDoubleData(mat, (double *)complex_data->Re, data_type, - sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadDoubleData(mat, &tmp, data_type, 1); - err |= readcount != 1; - readcount = ReadDoubleData(mat, (double *)complex_data->Im, data_type, - sparse->ndata); - err |= readcount != sparse->ndata; - readcount = ReadDoubleData(mat, &tmp, data_type, 1); - err |= readcount != 1; -#endif - if ( err ) { - ComplexFree(complex_data); - free(sparse->jc); - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - return MATIO_E_FILE_FORMAT_VIOLATION; - } - } else { - free(sparse->jc); - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical("Couldn't allocate memory for the complex sparse data"); - return MATIO_E_OUT_OF_MEMORY; - } - } else { - sparse->data = malloc(sparse->ndata * Mat_SizeOf(data_type)); - if ( sparse->data != NULL ) { -#if defined(EXTENDED_SPARSE) - switch ( data_type ) { - case MAT_T_DOUBLE: - readcount = ReadDoubleData(mat, (double *)sparse->data, data_type, - sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadDoubleData(mat, &tmp, data_type, 1); - err |= readcount != 1; - break; - case MAT_T_SINGLE: { - float tmp2; - readcount = ReadSingleData(mat, (float *)sparse->data, data_type, - sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadSingleData(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - case MAT_T_INT32: { - mat_int32_t tmp2; - readcount = ReadInt32Data(mat, (mat_int32_t *)sparse->data, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadInt32Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - case MAT_T_INT16: { - mat_int16_t tmp2; - readcount = ReadInt16Data(mat, (mat_int16_t *)sparse->data, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadInt16Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - case MAT_T_UINT16: { - mat_uint16_t tmp2; - readcount = ReadUInt16Data(mat, (mat_uint16_t *)sparse->data, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadUInt16Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - case MAT_T_UINT8: { - mat_uint8_t tmp2; - readcount = ReadUInt8Data(mat, (mat_uint8_t *)sparse->data, - data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadUInt8Data(mat, &tmp2, data_type, 1); - err |= readcount != 1; - break; - } - default: - free(sparse->data); - free(sparse->jc); - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical( - "Mat_VarRead4: %d is not a supported data type for " - "extended sparse", - data_type); - return MATIO_E_FILE_FORMAT_VIOLATION; - } -#else - readcount = - ReadDoubleData(mat, (double *)sparse->data, data_type, sparse->ndata); - err = readcount != sparse->ndata; - readcount = ReadDoubleData(mat, &tmp, data_type, 1); - err |= readcount != 1; -#endif - if ( err ) { - free(sparse->data); - free(sparse->jc); - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - return MATIO_E_FILE_FORMAT_VIOLATION; - } - } else { - free(sparse->jc); - free(sparse->ir); - free(matvar->data); - matvar->data = NULL; - Mat_Critical("Couldn't allocate memory for the sparse data"); - return MATIO_E_OUT_OF_MEMORY; - } - } - break; - } else { - Mat_Critical("Couldn't allocate memory for the data"); - return MATIO_E_OUT_OF_MEMORY; - } - default: - Mat_Critical("MAT V4 data type error"); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - - return MATIO_E_NO_ERROR; -} - -/** @if mat_devman - * @brief Reads a slab of data from a version 4 MAT file for the @c matvar variable - * - * @ingroup mat_internal - * @param mat Version 4 MAT file pointer - * @param matvar pointer to the mat variable - * @param data pointer to store the read data in (must be of size - * edge[0]*...edge[rank-1]*Mat_SizeOfClass(matvar->class_type)) - * @param start index to start reading data in each dimension - * @param stride write data every @c stride elements in each dimension - * @param edge number of elements to read in each dimension - * @retval 0 on success - * @endif - */ -static int -Mat_VarReadData4(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, int *edge) -{ - int err = MATIO_E_NO_ERROR; - - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - - switch ( matvar->data_type ) { - case MAT_T_DOUBLE: - case MAT_T_SINGLE: - case MAT_T_INT32: - case MAT_T_INT16: - case MAT_T_UINT16: - case MAT_T_UINT8: - break; - default: - return MATIO_E_FILE_FORMAT_VIOLATION; - } - - if ( matvar->rank == 2 ) { - if ( (size_t)stride[0] * (edge[0] - 1) + start[0] + 1 > matvar->dims[0] ) - err = MATIO_E_BAD_ARGUMENT; - else if ( (size_t)stride[1] * (edge[1] - 1) + start[1] + 1 > matvar->dims[1] ) - err = MATIO_E_BAD_ARGUMENT; - if ( matvar->isComplex ) { - mat_complex_split_t *cdata = (mat_complex_split_t *)data; - size_t nbytes = Mat_SizeOf(matvar->data_type); - err = Mat_MulDims(matvar, &nbytes); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - ReadDataSlab2(mat, cdata->Re, matvar->class_type, matvar->data_type, matvar->dims, - start, stride, edge); - (void)fseek((FILE *)mat->fp, matvar->internal->datapos + nbytes, SEEK_SET); - ReadDataSlab2(mat, cdata->Im, matvar->class_type, matvar->data_type, matvar->dims, - start, stride, edge); - } else { - ReadDataSlab2(mat, data, matvar->class_type, matvar->data_type, matvar->dims, start, - stride, edge); - } - } else if ( matvar->isComplex ) { - mat_complex_split_t *cdata = (mat_complex_split_t *)data; - size_t nbytes = Mat_SizeOf(matvar->data_type); - err = Mat_MulDims(matvar, &nbytes); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - ReadDataSlabN(mat, cdata->Re, matvar->class_type, matvar->data_type, matvar->rank, - matvar->dims, start, stride, edge); - (void)fseek((FILE *)mat->fp, matvar->internal->datapos + nbytes, SEEK_SET); - ReadDataSlabN(mat, cdata->Im, matvar->class_type, matvar->data_type, matvar->rank, - matvar->dims, start, stride, edge); - } else { - ReadDataSlabN(mat, data, matvar->class_type, matvar->data_type, matvar->rank, matvar->dims, - start, stride, edge); - } - - return err; -} - -/** @brief Reads a subset of a MAT variable using a 1-D indexing - * - * Reads data from a MAT variable using a linear (1-D) indexing mode. The - * variable must have been read by Mat_VarReadInfo. - * @ingroup MAT - * @param mat MAT file to read data from - * @param matvar MAT variable information - * @param data pointer to store data in (must be pre-allocated) - * @param start starting index - * @param stride stride of data - * @param edge number of elements to read - * @retval 0 on success - */ -static int -Mat_VarReadDataLinear4(mat_t *mat, matvar_t *matvar, void *data, int start, int stride, int edge) -{ - int err; - size_t nelems = 1; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - - matvar->data_size = Mat_SizeOf(matvar->data_type); - - if ( (size_t)stride * (edge - 1) + start + 1 > nelems ) { - return MATIO_E_BAD_ARGUMENT; - } - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)data; - err = Mul(&nelems, nelems, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - ReadDataSlab1(mat, complex_data->Re, matvar->class_type, matvar->data_type, start, stride, - edge); - (void)fseek((FILE *)mat->fp, matvar->internal->datapos + nelems, SEEK_SET); - ReadDataSlab1(mat, complex_data->Im, matvar->class_type, matvar->data_type, start, stride, - edge); - } else { - ReadDataSlab1(mat, data, matvar->class_type, matvar->data_type, start, stride, edge); - } - - return err; -} - -/** @if mat_devman - * @brief Reads the header information for the next MAT variable in a version 4 MAT file - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @return pointer to the MAT variable or NULL - * @endif - */ -static matvar_t * -Mat_VarReadNextInfo4(mat_t *mat) -{ - int M, O, data_type, class_type; - mat_int32_t tmp; - long nBytes, fpos; - matvar_t *matvar = NULL; - union { - mat_uint32_t u; - mat_uint8_t c[4]; - } endian; - - if ( mat == NULL || mat->fp == NULL ) - return NULL; - - if ( IsEndOfFile((FILE *)mat->fp, &fpos) ) - return NULL; - - if ( fpos == -1L ) - return NULL; - - { - size_t nbytes = 0; - int err = Read(&tmp, sizeof(mat_int32_t), 1, (FILE *)mat->fp, &nbytes); - if ( err || 0 == nbytes ) - return NULL; - } - - endian.u = 0x01020304; - - /* See if MOPT may need byteswapping */ - if ( tmp < 0 || tmp > 4052 ) { - if ( Mat_int32Swap(&tmp) > 4052 ) { - return NULL; - } - } - - M = (int)floor(tmp / 1000.0); - switch ( M ) { - case 0: - /* IEEE little endian */ - mat->byteswap = endian.c[0] != 4; - break; - case 1: - /* IEEE big endian */ - mat->byteswap = endian.c[0] != 1; - break; - default: - /* VAX, Cray, or bogus */ - return NULL; - } - - tmp -= M * 1000; - O = (int)floor(tmp / 100.0); - /* O must be zero */ - if ( 0 != O ) { - return NULL; - } - - if ( NULL == (matvar = Mat_VarCalloc()) ) - return NULL; - - tmp -= O * 100; - data_type = (int)floor(tmp / 10.0); - /* Convert the V4 data type */ - switch ( data_type ) { - case 0: - matvar->data_type = MAT_T_DOUBLE; - break; - case 1: - matvar->data_type = MAT_T_SINGLE; - break; - case 2: - matvar->data_type = MAT_T_INT32; - break; - case 3: - matvar->data_type = MAT_T_INT16; - break; - case 4: - matvar->data_type = MAT_T_UINT16; - break; - case 5: - matvar->data_type = MAT_T_UINT8; - break; - default: - Mat_VarFree(matvar); - return NULL; - } - - tmp -= data_type * 10; - class_type = (int)floor(tmp / 1.0); - switch ( class_type ) { - case 0: - matvar->class_type = MAT_C_DOUBLE; - break; - case 1: - matvar->class_type = MAT_C_CHAR; - break; - case 2: - matvar->class_type = MAT_C_SPARSE; - break; - default: - Mat_VarFree(matvar); - return NULL; - } - - matvar->rank = 2; - matvar->dims = (size_t *)calloc(2, sizeof(*matvar->dims)); - if ( NULL == matvar->dims ) { - Mat_VarFree(matvar); - return NULL; - } - if ( 0 != Read(&tmp, sizeof(int), 1, (FILE *)mat->fp, NULL) ) { - Mat_VarFree(matvar); - return NULL; - } - if ( mat->byteswap ) - Mat_int32Swap(&tmp); - matvar->dims[0] = tmp; - - if ( 0 != Read(&tmp, sizeof(int), 1, (FILE *)mat->fp, NULL) ) { - Mat_VarFree(matvar); - return NULL; - } - if ( mat->byteswap ) - Mat_int32Swap(&tmp); - matvar->dims[1] = tmp; - - if ( 0 != Read(&(matvar->isComplex), sizeof(int), 1, (FILE *)mat->fp, NULL) ) { - Mat_VarFree(matvar); - return NULL; - } - if ( matvar->isComplex && MAT_C_CHAR == matvar->class_type ) { - Mat_VarFree(matvar); - return NULL; - } - if ( 0 != Read(&tmp, sizeof(int), 1, (FILE *)mat->fp, NULL) ) { - Mat_VarFree(matvar); - return NULL; - } - if ( mat->byteswap ) - Mat_int32Swap(&tmp); - /* Check that the length of the variable name is at least 1 */ - if ( tmp < 1 ) { - Mat_VarFree(matvar); - return NULL; - } - matvar->name = (char *)malloc(tmp); - if ( NULL == matvar->name ) { - Mat_VarFree(matvar); - return NULL; - } - if ( 0 != Read(matvar->name, sizeof(char), tmp, (FILE *)mat->fp, NULL) ) { - Mat_VarFree(matvar); - return NULL; - } else { - matvar->name[tmp - 1] = '\0'; - } - - matvar->internal->datapos = ftell((FILE *)mat->fp); - if ( matvar->internal->datapos == -1L ) { - Mat_VarFree(matvar); - Mat_Critical("Couldn't determine file position"); - return NULL; - } - { - int err; - size_t tmp2 = Mat_SizeOf(matvar->data_type); - if ( matvar->isComplex ) - tmp2 *= 2; - err = Mat_MulDims(matvar, &tmp2); - if ( err ) { - Mat_VarFree(matvar); - Mat_Critical("Integer multiplication overflow"); - return NULL; - } - - nBytes = (long)tmp2; - } - (void)fseek((FILE *)mat->fp, nBytes, SEEK_CUR); - - return matvar; -} - -/* ------------------------------- - * ---------- mat5.c - * ------------------------------- - */ -/** @file mat5.c - * Matlab MAT version 5 file functions - * @ingroup MAT - */ - -/* FIXME: Implement Unicode support */ - -/** Get type from tag */ -#define TYPE_FROM_TAG(a) \ - (((a)&0x000000ff) <= MAT_T_FUNCTION) ? (enum matio_types)((a)&0x000000ff) : MAT_T_UNKNOWN -/** Get class from array flag */ -#define CLASS_FROM_ARRAY_FLAGS(a) \ - (((a)&0x000000ff) <= MAT_C_OPAQUE) ? ((enum matio_classes)((a)&0x000000ff)) : MAT_C_EMPTY -/** Class type mask */ -#define CLASS_TYPE_MASK 0x000000ff - -static mat_complex_split_t null_complex_data = {NULL, NULL}; - -/*=========================================================================== - * Private functions - *=========================================================================== - */ -static int GetTypeBufSize(matvar_t *matvar, size_t *size); -static int GetStructFieldBufSize(matvar_t *matvar, size_t *size); -static int GetCellArrayFieldBufSize(matvar_t *matvar, size_t *size); -static void SetFieldNames(matvar_t *matvar, char *buf, size_t nfields, - mat_uint32_t fieldname_length); -static size_t ReadSparse(mat_t *mat, matvar_t *matvar, mat_uint32_t *n, mat_uint32_t **v); -#if HAVE_ZLIB -static int GetMatrixMaxBufSize(matvar_t *matvar, size_t *size); -#endif -static int GetEmptyMatrixMaxBufSize(const char *name, int rank, size_t *size); -static size_t WriteCharData(mat_t *mat, void *data, size_t N, enum matio_types data_type); -static size_t ReadNextCell(mat_t *mat, matvar_t *matvar); -static size_t ReadNextStructField(mat_t *mat, matvar_t *matvar); -static size_t ReadNextFunctionHandle(mat_t *mat, matvar_t *matvar); -static int ReadRankDims(mat_t *mat, matvar_t *matvar, enum matio_types data_type, - mat_uint32_t nbytes, size_t *read_bytes); -static int WriteType(mat_t *mat, matvar_t *matvar); -static int WriteCellArrayField(mat_t *mat, matvar_t *matvar); -static int WriteStructField(mat_t *mat, matvar_t *matvar); -static int WriteData(mat_t *mat, void *data, size_t N, enum matio_types data_type); -static size_t Mat_WriteEmptyVariable5(mat_t *mat, const char *name, int rank, size_t *dims); -static int Mat_VarReadNumeric5(mat_t *mat, matvar_t *matvar, void *data, size_t N); -#if HAVE_ZLIB -static size_t WriteCompressedCharData(mat_t *mat, z_streamp z, void *data, size_t N, - enum matio_types data_type); -static size_t WriteCompressedData(mat_t *mat, z_streamp z, void *data, int N, - enum matio_types data_type); -static size_t WriteCompressedTypeArrayFlags(mat_t *mat, matvar_t *matvar, z_streamp z); -static size_t WriteCompressedType(mat_t *mat, matvar_t *matvar, z_streamp z); -static size_t WriteCompressedCellArrayField(mat_t *mat, matvar_t *matvar, z_streamp z); -static size_t WriteCompressedStructField(mat_t *mat, matvar_t *matvar, z_streamp z); -static size_t Mat_WriteCompressedEmptyVariable5(mat_t *mat, const char *name, int rank, - size_t *dims, z_streamp z); -#endif - -/** @brief determines the number of bytes for a given class type - * - * @ingroup mat_internal - * @param matvar MAT variable - * @param size the number of bytes needed to store the MAT variable - * @return 0 on success - */ -static int -GetTypeBufSize(matvar_t *matvar, size_t *size) -{ - int err; - size_t nBytes, data_bytes; - size_t tag_size = 8; - size_t nelems = 1; - size_t rank_size; - - *size = 0; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) - return err; - - /* Add rank and dimensions, padded to an 8 byte block */ - err = Mul(&rank_size, matvar->rank, 4); - if ( err ) - return err; - - if ( matvar->rank % 2 ) - nBytes = tag_size + 4; - else - nBytes = tag_size; - - err = Add(&nBytes, nBytes, rank_size); - if ( err ) - return err; - - switch ( matvar->class_type ) { - case MAT_C_STRUCT: { - matvar_t **fields = (matvar_t **)matvar->data; - size_t nfields = matvar->internal->num_fields; - size_t maxlen = 0, i, field_buf_size; - - for ( i = 0; i < nfields; i++ ) { - char *fieldname = matvar->internal->fieldnames[i]; - if ( NULL != fieldname && strlen(fieldname) > maxlen ) - maxlen = strlen(fieldname); - } - maxlen++; - while ( nfields * maxlen % 8 != 0 ) - maxlen++; - - err = Mul(&field_buf_size, maxlen, nfields); - if ( err ) - return err; - err = Add(&nBytes, nBytes, tag_size + tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, field_buf_size); - if ( err ) - return err; - - /* FIXME: Add bytes for the fieldnames */ - if ( NULL != fields && nfields > 0 ) { - size_t nelems_x_nfields = 1; - err = Mul(&nelems_x_nfields, nelems, nfields); - if ( err ) - return err; - - for ( i = 0; i < nelems_x_nfields; i++ ) { - err = GetStructFieldBufSize(fields[i], &field_buf_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, field_buf_size); - if ( err ) - return err; - } - } - break; - } - case MAT_C_CELL: { - matvar_t **cells = (matvar_t **)matvar->data; - - if ( matvar->nbytes == 0 || matvar->data_size == 0 ) - break; - - nelems = matvar->nbytes / matvar->data_size; - if ( NULL != cells && nelems > 0 ) { - size_t i, field_buf_size; - for ( i = 0; i < nelems; i++ ) { - err = GetCellArrayFieldBufSize(cells[i], &field_buf_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, field_buf_size); - if ( err ) - return err; - } - } - break; - } - case MAT_C_SPARSE: { - mat_sparse_t *sparse = (mat_sparse_t *)matvar->data; - - err = Mul(&data_bytes, sparse->nir, sizeof(mat_uint32_t)); - if ( err ) - return err; - if ( data_bytes % 8 ) { - err = Add(&data_bytes, data_bytes, 8 - data_bytes % 8); - if ( err ) - return err; - } - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, data_bytes); - if ( err ) - return err; - - err = Mul(&data_bytes, sparse->njc, sizeof(mat_uint32_t)); - if ( err ) - return err; - if ( data_bytes % 8 ) { - err = Add(&data_bytes, data_bytes, 8 - data_bytes % 8); - if ( err ) - return err; - } - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, data_bytes); - if ( err ) - return err; - - err = Mul(&data_bytes, sparse->ndata, Mat_SizeOf(matvar->data_type)); - if ( err ) - return err; - if ( data_bytes % 8 ) { - err = Add(&data_bytes, data_bytes, 8 - data_bytes % 8); - if ( err ) - return err; - } - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, data_bytes); - if ( err ) - return err; - - if ( matvar->isComplex ) { - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, data_bytes); - if ( err ) - return err; - } - - break; - } - case MAT_C_CHAR: - if ( MAT_T_UINT8 == matvar->data_type || MAT_T_INT8 == matvar->data_type ) - err = Mul(&data_bytes, nelems, Mat_SizeOf(MAT_T_UINT16)); - else - err = Mul(&data_bytes, nelems, Mat_SizeOf(matvar->data_type)); - if ( err ) - return err; - if ( data_bytes % 8 ) { - err = Add(&data_bytes, data_bytes, 8 - data_bytes % 8); - if ( err ) - return err; - } - - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, data_bytes); - if ( err ) - return err; - - if ( matvar->isComplex ) { - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, data_bytes); - if ( err ) - return err; - } - - break; - default: - err = Mul(&data_bytes, nelems, Mat_SizeOf(matvar->data_type)); - if ( err ) - return err; - if ( data_bytes % 8 ) { - err = Add(&data_bytes, data_bytes, 8 - data_bytes % 8); - if ( err ) - return err; - } - - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, data_bytes); - if ( err ) - return err; - - if ( matvar->isComplex ) { - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, data_bytes); - if ( err ) - return err; - } - } /* switch ( matvar->class_type ) */ - - *size = nBytes; - return MATIO_E_NO_ERROR; -} - -/** @brief determines the number of bytes needed to store the given struct field - * - * @ingroup mat_internal - * @param matvar field of a structure - * @param size the number of bytes needed to store the struct field - * @return 0 on success - */ -static int -GetStructFieldBufSize(matvar_t *matvar, size_t *size) -{ - int err; - size_t nBytes = 0, type_buf_size; - size_t tag_size = 8, array_flags_size = 8; - - *size = 0; - - if ( matvar == NULL ) - return GetEmptyMatrixMaxBufSize(NULL, 2, size); - - /* Add the Array Flags tag and space to the number of bytes */ - nBytes += tag_size + array_flags_size; - - /* In a struct field, the name is just a tag with 0 bytes */ - nBytes += tag_size; - - err = GetTypeBufSize(matvar, &type_buf_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, type_buf_size); - if ( err ) - return err; - - *size = nBytes; - return MATIO_E_NO_ERROR; -} - -/** @brief determines the number of bytes needed to store the cell array element - * - * @ingroup mat_internal - * @param matvar MAT variable - * @param size the number of bytes needed to store the variable - * @return 0 on success - */ -static int -GetCellArrayFieldBufSize(matvar_t *matvar, size_t *size) -{ - int err; - size_t nBytes = 0, type_buf_size; - size_t tag_size = 8, array_flags_size = 8; - - *size = 0; - - if ( matvar == NULL ) - return MATIO_E_BAD_ARGUMENT; - - /* Add the Array Flags tag and space to the number of bytes */ - nBytes += tag_size + array_flags_size; - - /* In an element of a cell array, the name is just a tag with 0 bytes */ - nBytes += tag_size; - - err = GetTypeBufSize(matvar, &type_buf_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, type_buf_size); - if ( err ) - return err; - - *size = nBytes; - return MATIO_E_NO_ERROR; -} - -/** @brief determines the number of bytes needed to store the given variable - * - * @ingroup mat_internal - * @param matvar MAT variable - * @param rank rank of the variable - * @param size the number of bytes needed to store the variable - * @return 0 on success - */ -static int -GetEmptyMatrixMaxBufSize(const char *name, int rank, size_t *size) -{ - int err = 0; - size_t nBytes = 0, len, rank_size; - size_t tag_size = 8, array_flags_size = 8; - - /* Add the Array Flags tag and space to the number of bytes */ - nBytes += tag_size + array_flags_size; - - /* Get size of variable name, pad it to an 8 byte block, and add it to nBytes */ - if ( NULL != name ) - len = strlen(name); - else - len = 4; - - if ( len <= 4 ) { - nBytes += tag_size; - } else { - nBytes += tag_size; - if ( len % 8 ) { - err = Add(&len, len, 8 - len % 8); - if ( err ) - return err; - } - - err = Add(&nBytes, nBytes, len); - if ( err ) - return err; - } - - /* Add rank and dimensions, padded to an 8 byte block */ - err = Mul(&rank_size, rank, 4); - if ( err ) - return err; - if ( rank % 2 ) - err = Add(&nBytes, nBytes, tag_size + 4); - else - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - - err = Add(&nBytes, nBytes, rank_size); - if ( err ) - return err; - /* Data tag */ - err = Add(&nBytes, nBytes, tag_size); - if ( err ) - return err; - - *size = nBytes; - return MATIO_E_NO_ERROR; -} - -static void -SetFieldNames(matvar_t *matvar, char *buf, size_t nfields, mat_uint32_t fieldname_length) -{ - matvar->internal->num_fields = nfields; - matvar->internal->fieldnames = (char **)calloc(nfields, sizeof(*matvar->internal->fieldnames)); - if ( NULL != matvar->internal->fieldnames ) { - size_t i; - for ( i = 0; i < nfields; i++ ) { - matvar->internal->fieldnames[i] = (char *)malloc(fieldname_length); - if ( NULL != matvar->internal->fieldnames[i] ) { - memcpy(matvar->internal->fieldnames[i], buf + i * fieldname_length, - fieldname_length); - matvar->internal->fieldnames[i][fieldname_length - 1] = '\0'; - } - } - } -} - -static size_t -ReadSparse(mat_t *mat, matvar_t *matvar, mat_uint32_t *n, mat_uint32_t **v) -{ - int data_in_tag = 0; - enum matio_types packed_type; - mat_uint32_t tag[2]; - size_t bytesread = 0; - mat_uint32_t N = 0; - - if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { -#if HAVE_ZLIB - matvar->internal->z->avail_in = 0; - if ( 0 != Inflate(mat, matvar->internal->z, tag, 4, &bytesread) ) { - return bytesread; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(tag); - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - N = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - (void)ReadCompressedUInt32Data(mat, matvar->internal->z, &N, MAT_T_UINT32, 1); - } -#endif - } else { - if ( 0 != Read(tag, 4, 1, (FILE *)mat->fp, &bytesread) ) { - return bytesread; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(tag); - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - N = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - if ( 0 != Read(&N, 4, 1, (FILE *)mat->fp, &bytesread) ) { - return bytesread; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(&N); - } - } - if ( 0 == N ) - return bytesread; - *n = N / 4; - *v = (mat_uint32_t *)calloc(N, 1); - if ( NULL != *v ) { - int nBytes; - if ( matvar->compression == MAT_COMPRESSION_NONE ) { - nBytes = ReadUInt32Data(mat, *v, packed_type, *n); - /* - * If the data was in the tag we started on a 4-byte - * boundary so add 4 to make it an 8-byte - */ - nBytes *= Mat_SizeOf(packed_type); - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - (void)fseek((FILE *)mat->fp, 8 - (nBytes % 8), SEEK_CUR); -#if HAVE_ZLIB - } else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - nBytes = ReadCompressedUInt32Data(mat, matvar->internal->z, *v, packed_type, *n); - /* - * If the data was in the tag we started on a 4-byte - * boundary so add 4 to make it an 8-byte - */ - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - InflateSkip(mat, matvar->internal->z, 8 - (nBytes % 8), NULL); -#endif - } - } else { - Mat_Critical("Couldn't allocate memory"); - } - - return bytesread; -} - -#if HAVE_ZLIB -/** @brief determines the number of bytes needed to store the given variable - * - * @ingroup mat_internal - * @param matvar MAT variable - * @param size the number of bytes needed to store the variable - * @return 0 on success - */ -static int -GetMatrixMaxBufSize(matvar_t *matvar, size_t *size) -{ - int err = MATIO_E_NO_ERROR; - size_t nBytes = 0, len, type_buf_size; - size_t tag_size = 8, array_flags_size = 8; - - if ( matvar == NULL ) - return MATIO_E_BAD_ARGUMENT; - - /* Add the Array Flags tag and space to the number of bytes */ - nBytes += tag_size + array_flags_size; - - /* Get size of variable name, pad it to an 8 byte block, and add it to nBytes */ - if ( NULL != matvar->name ) - len = strlen(matvar->name); - else - len = 4; - - if ( len <= 4 ) { - nBytes += tag_size; - } else { - nBytes += tag_size; - if ( len % 8 ) { - err = Add(&len, len, 8 - len % 8); - if ( err ) - return err; - } - - err = Add(&nBytes, nBytes, len); - if ( err ) - return err; - } - - err = GetTypeBufSize(matvar, &type_buf_size); - if ( err ) - return err; - err = Add(&nBytes, nBytes, type_buf_size); - if ( err ) - return err; - - *size = nBytes; - return MATIO_E_NO_ERROR; -} -#endif - -/** @if mat_devman - * @brief Creates a new Matlab MAT version 5 file - * - * Tries to create a new Matlab MAT file with the given name and optional - * header string. If no header string is given, the default string - * is used containing the software, version, and date in it. If a header - * string is given, at most the first 116 characters is written to the file. - * The given header string need not be the full 116 characters, but MUST be - * NULL terminated. - * @ingroup MAT - * @param matname Name of MAT file to create - * @param hdr_str Optional header string, NULL to use default - * @return A pointer to the MAT file or NULL if it failed. This is not a - * simple FILE * and should not be used as one. - * @endif - */ -static mat_t * -Mat_Create5(const char *matname, const char *hdr_str) -{ - FILE *fp = NULL; - mat_int16_t endian = 0, version; - mat_t *mat = NULL; - size_t err; - time_t t; - -#if defined(_WIN32) && defined(_MSC_VER) - wchar_t *wname = utf82u(matname); - if ( NULL != wname ) { - fp = _wfopen(wname, L"w+b"); - free(wname); - } -#else - fp = fopen(matname, "w+b"); -#endif - if ( !fp ) - return NULL; - - mat = (mat_t *)malloc(sizeof(*mat)); - if ( mat == NULL ) { - fclose(fp); - return NULL; - } - - mat->fp = NULL; - mat->header = NULL; - mat->subsys_offset = NULL; - mat->filename = NULL; - mat->version = 0; - mat->byteswap = 0; - mat->mode = 0; - mat->bof = 128; - mat->next_index = 0; - mat->num_datasets = 0; -#if HAVE_HDF5 - mat->refs_id = -1; -#endif - mat->dir = NULL; - - t = time(NULL); - mat->fp = fp; - mat->filename = Mat_strdup(matname); - mat->mode = MAT_ACC_RDWR; - mat->byteswap = 0; - mat->header = (char *)malloc(128 * sizeof(char)); - mat->subsys_offset = (char *)malloc(8 * sizeof(char)); - memset(mat->header, ' ', 128); - if ( hdr_str == NULL ) { - err = mat_snprintf(mat->header, 116, - "MATLAB 5.0 MAT-file, Platform: %s, " - "Created by: libmatio v%d.%d.%d on %s", - MATIO_PLATFORM, MATIO_MAJOR_VERSION, MATIO_MINOR_VERSION, - MATIO_RELEASE_LEVEL, ctime(&t)); - } else { - err = mat_snprintf(mat->header, 116, "%s", hdr_str); - } - if ( err >= 116 ) - mat->header[115] = '\0'; /* Just to make sure it's NULL terminated */ - memset(mat->subsys_offset, ' ', 8); - mat->version = (int)0x0100; - endian = 0x4d49; - - version = 0x0100; - - fwrite(mat->header, 1, 116, (FILE *)mat->fp); - fwrite(mat->subsys_offset, 1, 8, (FILE *)mat->fp); - fwrite(&version, 2, 1, (FILE *)mat->fp); - fwrite(&endian, 2, 1, (FILE *)mat->fp); - - return mat; -} - -/** @if mat_devman - * @brief Writes @c data as character data - * - * This function uses the knowledge that the data is part of a character class - * to avoid some pitfalls with Matlab listed below. - * @li Matlab character data cannot be unsigned 8-bit integers, it needs at - * least unsigned 16-bit integers - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param data character data to write - * @param N Number of elements to write - * @param data_type character data type (enum matio_types) - * @return number of bytes written - * @endif - */ -static size_t -WriteCharData(mat_t *mat, void *data, size_t N, enum matio_types data_type) -{ - mat_uint32_t nBytes = 0; - size_t nbytes, i; - size_t byteswritten = 0; - const mat_uint8_t pad1 = 0; - int err; - - switch ( data_type ) { - case MAT_T_UINT8: - case MAT_T_UINT16: - case MAT_T_UTF8: - case MAT_T_UTF16: { - data_type = MAT_T_UINT8 == data_type ? MAT_T_UTF8 : data_type; - err = Mul(&nbytes, N, Mat_SizeOf(data_type)); - if ( err ) { - return 0; - } - nBytes = (mat_uint32_t)nbytes; - fwrite(&data_type, 4, 1, (FILE *)mat->fp); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - if ( NULL != data && N > 0 ) - fwrite(data, 1, nbytes, (FILE *)mat->fp); - if ( nBytes % 8 ) { - for ( i = nbytes % 8; i < 8; i++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } - break; - } - case MAT_T_INT8: { - mat_int8_t *ptr; - mat_uint16_t c; - - /* Matlab can't read MAT_C_CHAR as int8, needs uint16 */ - data_type = MAT_T_UINT16; - err = Mul(&nbytes, N, Mat_SizeOf(data_type)); - if ( err ) { - return 0; - } - nBytes = (mat_uint32_t)nbytes; - fwrite(&data_type, 4, 1, (FILE *)mat->fp); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - ptr = (mat_int8_t *)data; - if ( NULL == data ) - break; - for ( i = 0; i < N; i++ ) { - c = (mat_uint16_t) * (char *)ptr; - fwrite(&c, 2, 1, (FILE *)mat->fp); - ptr++; - } - if ( nbytes % 8 ) - for ( i = nbytes % 8; i < 8; i++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - break; - } - case MAT_T_UNKNOWN: { - /* Sometimes empty char data will have MAT_T_UNKNOWN, so just write - * a data tag - */ - data_type = MAT_T_UINT16; - err = Mul(&nbytes, N, Mat_SizeOf(data_type)); - if ( err ) { - return 0; - } - nBytes = (mat_uint32_t)nbytes; - fwrite(&data_type, 4, 1, (FILE *)mat->fp); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - break; - } - default: - nbytes = 0; - break; - } - byteswritten += nbytes; - return byteswritten; -} - -#if HAVE_ZLIB -/** @brief Writes @c data as compressed character data - * - * This function uses the knowledge that the data is part of a character class - * to avoid some pitfalls with Matlab listed below. - * @li Matlab character data cannot be unsigned 8-bit integers, it needs at - * least unsigned 16-bit integers - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param z pointer to the zlib compression stream - * @param data character data to write - * @param N Number of elements to write - * @param data_type character data type (enum matio_types) - * @return number of bytes written - */ -static size_t -WriteCompressedCharData(mat_t *mat, z_streamp z, void *data, size_t N, enum matio_types data_type) -{ - size_t data_size, byteswritten = 0, nbytes; - mat_uint32_t data_tag[2]; - int buf_size = 1024; - int err; - mat_uint8_t buf[1024], pad[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - if ( mat == NULL || mat->fp == NULL ) - return 0; - - if ( data_type == MAT_T_UNKNOWN ) { - data_size = Mat_SizeOf(MAT_T_UINT16); - } else { - data_size = Mat_SizeOf(data_type); - } - - err = Mul(&nbytes, N, data_size); - if ( err ) { - return byteswritten; - } - - switch ( data_type ) { - case MAT_T_UINT8: - case MAT_T_UINT16: - case MAT_T_UTF8: - case MAT_T_UTF16: - data_tag[0] = MAT_T_UINT8 == data_type ? MAT_T_UTF8 : data_type; - data_tag[1] = (mat_uint32_t)nbytes; - z->next_in = ZLIB_BYTE_PTR(data_tag); - z->avail_in = 8; - do { - z->next_out = buf; - z->avail_out = buf_size; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(buf, 1, buf_size - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - - /* exit early if this is an empty data */ - if ( NULL == data || N < 1 ) - break; - - z->next_in = (Bytef *)data; - z->avail_in = (mat_uint32_t)nbytes; - do { - z->next_out = buf; - z->avail_out = buf_size; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(buf, 1, buf_size - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - /* Add/Compress padding to pad to 8-byte boundary */ - if ( nbytes % 8 ) { - z->next_in = pad; - z->avail_in = 8 - (nbytes % 8); - do { - z->next_out = buf; - z->avail_out = buf_size; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(buf, 1, buf_size - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - } - break; - case MAT_T_UNKNOWN: - /* Sometimes empty char data will have MAT_T_UNKNOWN, so just write a data tag */ - data_tag[0] = MAT_T_UINT16; - data_tag[1] = (mat_uint32_t)nbytes; - z->next_in = ZLIB_BYTE_PTR(data_tag); - z->avail_in = 8; - do { - z->next_out = buf; - z->avail_out = buf_size; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(buf, 1, buf_size - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - break; - default: - break; - } - - return byteswritten; -} -#endif - -/** @brief Writes the data buffer to the file - * - * @param mat MAT file pointer - * @param data pointer to the data to write - * @param N number of elements to write - * @param data_type data type of the data - * @return number of bytes written - */ -static int -WriteData(mat_t *mat, void *data, size_t N, enum matio_types data_type) -{ - int nBytes = 0, data_size; - - if ( mat == NULL || mat->fp == NULL ) - return 0; - - data_size = Mat_SizeOf(data_type); - nBytes = N * data_size; - fwrite(&data_type, 4, 1, (FILE *)mat->fp); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - - if ( data != NULL && N > 0 ) - fwrite(data, data_size, N, (FILE *)mat->fp); - - return nBytes; -} - -#if HAVE_ZLIB -/* Compresses the data buffer and writes it to the file */ -static size_t -WriteCompressedData(mat_t *mat, z_streamp z, void *data, int N, enum matio_types data_type) -{ - int nBytes = 0, data_size, data_tag[2], byteswritten = 0; - int buf_size = 1024; - mat_uint8_t buf[1024], pad[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - if ( mat == NULL || mat->fp == NULL ) - return 0; - - data_size = Mat_SizeOf(data_type); - data_tag[0] = data_type; - data_tag[1] = data_size * N; - z->next_in = ZLIB_BYTE_PTR(data_tag); - z->avail_in = 8; - do { - z->next_out = buf; - z->avail_out = buf_size; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(buf, 1, buf_size - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - - /* exit early if this is an empty data */ - if ( NULL == data || N < 1 ) - return byteswritten; - - z->next_in = (Bytef *)data; - z->avail_in = N * data_size; - do { - z->next_out = buf; - z->avail_out = buf_size; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(buf, 1, buf_size - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - /* Add/Compress padding to pad to 8-byte boundary */ - if ( N * data_size % 8 ) { - z->next_in = pad; - z->avail_in = 8 - (N * data_size % 8); - do { - z->next_out = buf; - z->avail_out = buf_size; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(buf, 1, buf_size - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - } - nBytes = byteswritten; - return nBytes; -} -#endif - -/** @brief Reads the next cell of the cell array in @c matvar - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar MAT variable pointer - * @return Number of bytes read - */ -static size_t -ReadNextCell(mat_t *mat, matvar_t *matvar) -{ - size_t bytesread = 0, i; - int err; - matvar_t **cells = NULL; - size_t nelems = 1; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return bytesread; - } - matvar->data_size = sizeof(matvar_t *); - err = Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return bytesread; - } - - matvar->data = calloc(nelems, matvar->data_size); - if ( NULL == matvar->data ) { - if ( NULL != matvar->name ) - Mat_Critical("Couldn't allocate memory for %s->data", matvar->name); - return bytesread; - } - cells = (matvar_t **)matvar->data; - - if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { -#if HAVE_ZLIB - mat_uint32_t uncomp_buf[16]; - mat_uint32_t nBytes; - mat_uint32_t array_flags; - - memset(&uncomp_buf, 0, sizeof(uncomp_buf)); - for ( i = 0; i < nelems; i++ ) { - cells[i] = Mat_VarCalloc(); - if ( NULL == cells[i] ) { - Mat_Critical("Couldn't allocate memory for cell %zu", i); - continue; - } - - /* Read variable tag for cell */ - uncomp_buf[0] = 0; - uncomp_buf[1] = 0; - err = Inflate(mat, matvar->internal->z, uncomp_buf, 8, &bytesread); - if ( err ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - } - nBytes = uncomp_buf[1]; - if ( 0 == nBytes ) { - /* Empty cell: Memory optimization */ - free(cells[i]->internal); - cells[i]->internal = NULL; - continue; - } else if ( uncomp_buf[0] != MAT_T_MATRIX ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - Mat_Critical("cells[%zu], Uncompressed type not MAT_T_MATRIX", i); - break; - } - cells[i]->compression = MAT_COMPRESSION_ZLIB; - err = Inflate(mat, matvar->internal->z, uncomp_buf, 16, &bytesread); - if ( err ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - nBytes -= 16; - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - (void)Mat_uint32Swap(uncomp_buf + 2); - (void)Mat_uint32Swap(uncomp_buf + 3); - } - /* Array Flags */ - if ( uncomp_buf[0] == MAT_T_UINT32 ) { - array_flags = uncomp_buf[2]; - cells[i]->class_type = CLASS_FROM_ARRAY_FLAGS(array_flags); - cells[i]->isComplex = (array_flags & MAT_F_COMPLEX); - cells[i]->isGlobal = (array_flags & MAT_F_GLOBAL); - cells[i]->isLogical = (array_flags & MAT_F_LOGICAL); - if ( cells[i]->class_type == MAT_C_SPARSE ) { - /* Need to find a more appropriate place to store nzmax */ - cells[i]->nbytes = uncomp_buf[3]; - } - } else { - Mat_Critical("Expected MAT_T_UINT32 for array tags, got %d", uncomp_buf[0]); - InflateSkip(mat, matvar->internal->z, nBytes, &bytesread); - } - if ( cells[i]->class_type != MAT_C_OPAQUE ) { - mat_uint32_t *dims = NULL; - int do_clean = 0; - err = InflateRankDims(mat, matvar->internal->z, uncomp_buf, sizeof(uncomp_buf), - &dims, &bytesread); - if ( NULL == dims ) { - dims = uncomp_buf + 2; - } else { - do_clean = 1; - } - if ( err ) { - if ( do_clean ) { - free(dims); - } - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - nBytes -= 8; - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - } - /* Rank and Dimension */ - if ( uncomp_buf[0] == MAT_T_INT32 ) { - int j; - size_t size; - cells[i]->rank = uncomp_buf[1]; - nBytes -= cells[i]->rank; - cells[i]->rank /= 4; - if ( 0 == do_clean && cells[i]->rank > 13 ) { - int rank = cells[i]->rank; - cells[i]->rank = 0; - Mat_Critical("%d is not a valid rank", rank); - continue; - } - err = Mul(&size, cells[i]->rank, sizeof(*cells[i]->dims)); - if ( err ) { - if ( do_clean ) { - free(dims); - } - Mat_VarFree(cells[i]); - cells[i] = NULL; - Mat_Critical("Integer multiplication overflow"); - continue; - } - cells[i]->dims = (size_t *)malloc(size); - if ( mat->byteswap ) { - for ( j = 0; j < cells[i]->rank; j++ ) - cells[i]->dims[j] = Mat_uint32Swap(dims + j); - } else { - for ( j = 0; j < cells[i]->rank; j++ ) - cells[i]->dims[j] = dims[j]; - } - if ( cells[i]->rank % 2 != 0 ) - nBytes -= 4; - } - if ( do_clean ) { - free(dims); - } - /* Variable name tag */ - err = Inflate(mat, matvar->internal->z, uncomp_buf, 8, &bytesread); - if ( err ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - nBytes -= 8; - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - } - /* Handle cell elements written with a variable name */ - if ( uncomp_buf[1] > 0 ) { - /* Name of variable */ - if ( uncomp_buf[0] == MAT_T_INT8 ) { /* Name not in tag */ - mat_uint32_t len = uncomp_buf[1]; - - if ( len % 8 > 0 ) { - if ( len < UINT32_MAX - 8 + (len % 8) ) - len = len + 8 - (len % 8); - else { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - } - cells[i]->name = (char *)malloc(len + 1); - nBytes -= len; - if ( NULL != cells[i]->name ) { - /* Variable name */ - err = - Inflate(mat, matvar->internal->z, cells[i]->name, len, &bytesread); - if ( err ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - cells[i]->name[len] = '\0'; - } - } else { - mat_uint32_t len = (uncomp_buf[0] & 0xffff0000) >> 16; - if ( ((uncomp_buf[0] & 0x0000ffff) == MAT_T_INT8) && len > 0 && len <= 4 ) { - /* Name packed in tag */ - cells[i]->name = (char *)malloc(len + 1); - if ( NULL != cells[i]->name ) { - memcpy(cells[i]->name, uncomp_buf + 1, len); - cells[i]->name[len] = '\0'; - } - } - } - } - cells[i]->internal->z = (z_streamp)calloc(1, sizeof(z_stream)); - if ( cells[i]->internal->z != NULL ) { - err = inflateCopy(cells[i]->internal->z, matvar->internal->z); - if ( err == Z_OK ) { - cells[i]->internal->datapos = ftell((FILE *)mat->fp); - if ( cells[i]->internal->datapos != -1L ) { - cells[i]->internal->datapos -= matvar->internal->z->avail_in; - if ( cells[i]->class_type == MAT_C_STRUCT ) - bytesread += ReadNextStructField(mat, cells[i]); - else if ( cells[i]->class_type == MAT_C_CELL ) - bytesread += ReadNextCell(mat, cells[i]); - else if ( nBytes <= (1 << MAX_WBITS) ) { - /* Memory optimization: Read data if less in size - than the zlib inflate state (approximately) */ - err = Mat_VarRead5(mat, cells[i]); - cells[i]->internal->data = cells[i]->data; - cells[i]->data = NULL; - } - (void)fseek((FILE *)mat->fp, cells[i]->internal->datapos, SEEK_SET); - } else { - Mat_Critical("Couldn't determine file position"); - } - if ( cells[i]->internal->data != NULL || - cells[i]->class_type == MAT_C_STRUCT || - cells[i]->class_type == MAT_C_CELL ) { - /* Memory optimization: Free inflate state */ - inflateEnd(cells[i]->internal->z); - free(cells[i]->internal->z); - cells[i]->internal->z = NULL; - } - } else { - Mat_Critical("inflateCopy returned error %s", zError(err)); - } - } else { - Mat_Critical("Couldn't allocate memory"); - } - } - InflateSkip(mat, matvar->internal->z, nBytes, &bytesread); - } -#else - Mat_Critical("Not compiled with zlib support"); -#endif - - } else { - mat_uint32_t buf[6] = {0, 0, 0, 0, 0, 0}; - mat_uint32_t nBytes; - mat_uint32_t array_flags; - - for ( i = 0; i < nelems; i++ ) { - size_t nbytes = 0; - mat_uint32_t name_len; - cells[i] = Mat_VarCalloc(); - if ( NULL == cells[i] ) { - Mat_Critical("Couldn't allocate memory for cell %zu", i); - continue; - } - - /* Read variable tag for cell */ - err = Read(buf, 4, 2, (FILE *)mat->fp, &nbytes); - - /* Empty cells at the end of a file may cause an EOF */ - if ( 0 == err && 0 == nbytes ) - continue; - bytesread += nbytes; - if ( err ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(buf); - (void)Mat_uint32Swap(buf + 1); - } - nBytes = buf[1]; - if ( 0 == nBytes ) { - /* Empty cell: Memory optimization */ - free(cells[i]->internal); - cells[i]->internal = NULL; - continue; - } else if ( buf[0] != MAT_T_MATRIX ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - Mat_Critical("cells[%zu] not MAT_T_MATRIX, fpos = %ld", i, ftell((FILE *)mat->fp)); - break; - } - - /* Read array flags and the dimensions tag */ - err = Read(buf, 4, 6, (FILE *)mat->fp, &bytesread); - if ( err ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(buf); - (void)Mat_uint32Swap(buf + 1); - (void)Mat_uint32Swap(buf + 2); - (void)Mat_uint32Swap(buf + 3); - (void)Mat_uint32Swap(buf + 4); - (void)Mat_uint32Swap(buf + 5); - } - nBytes -= 24; - /* Array flags */ - if ( buf[0] == MAT_T_UINT32 ) { - array_flags = buf[2]; - cells[i]->class_type = CLASS_FROM_ARRAY_FLAGS(array_flags); - cells[i]->isComplex = (array_flags & MAT_F_COMPLEX); - cells[i]->isGlobal = (array_flags & MAT_F_GLOBAL); - cells[i]->isLogical = (array_flags & MAT_F_LOGICAL); - if ( cells[i]->class_type == MAT_C_SPARSE ) { - /* Need to find a more appropriate place to store nzmax */ - cells[i]->nbytes = buf[3]; - } - } - /* Rank and dimension */ - nbytes = 0; - err = ReadRankDims(mat, cells[i], (enum matio_types)buf[4], buf[5], &nbytes); - bytesread += nbytes; - nBytes -= nbytes; - if ( err ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - /* Variable name tag */ - if ( 0 != Read(buf, 1, 8, (FILE *)mat->fp, &bytesread) ) { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - nBytes -= 8; - if ( mat->byteswap ) { - (void)Mat_uint32Swap(buf); - (void)Mat_uint32Swap(buf + 1); - } - name_len = 0; - if ( buf[1] > 0 ) { - /* Name of variable */ - if ( buf[0] == MAT_T_INT8 ) { /* Name not in tag */ - name_len = buf[1]; - if ( name_len % 8 > 0 ) { - if ( name_len < UINT32_MAX - 8 + (name_len % 8) ) { - name_len = name_len + 8 - (name_len % 8); - } else { - Mat_VarFree(cells[i]); - cells[i] = NULL; - break; - } - } - nBytes -= name_len; - (void)fseek((FILE *)mat->fp, name_len, SEEK_CUR); - } - } - cells[i]->internal->datapos = ftell((FILE *)mat->fp); - if ( cells[i]->internal->datapos != -1L ) { - if ( cells[i]->class_type == MAT_C_STRUCT ) - bytesread += ReadNextStructField(mat, cells[i]); - if ( cells[i]->class_type == MAT_C_CELL ) - bytesread += ReadNextCell(mat, cells[i]); - (void)fseek((FILE *)mat->fp, cells[i]->internal->datapos + nBytes, SEEK_SET); - } else { - Mat_Critical("Couldn't determine file position"); - } - } - } - - return bytesread; -} - -/** @brief Reads the next struct field of the structure in @c matvar - * - * Reads the next struct fields (fieldname length,names,data headers for all - * the fields - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar MAT variable pointer - * @return Number of bytes read - */ -static size_t -ReadNextStructField(mat_t *mat, matvar_t *matvar) -{ - mat_uint32_t fieldname_size; - int err; - size_t bytesread = 0, nfields, i; - matvar_t **fields = NULL; - size_t nelems = 1, nelems_x_nfields; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return bytesread; - } - if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { -#if HAVE_ZLIB - mat_uint32_t uncomp_buf[16]; - mat_uint32_t array_flags, len; - - memset(&uncomp_buf, 0, sizeof(uncomp_buf)); - /* Field name length */ - err = Inflate(mat, matvar->internal->z, uncomp_buf, 8, &bytesread); - if ( err ) { - return bytesread; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - } - if ( (uncomp_buf[0] & 0x0000ffff) == MAT_T_INT32 && uncomp_buf[1] > 0 ) { - fieldname_size = uncomp_buf[1]; - } else { - Mat_Critical("Error getting fieldname size"); - return bytesread; - } - - /* Field name tag */ - err = Inflate(mat, matvar->internal->z, uncomp_buf, 8, &bytesread); - if ( err ) { - return bytesread; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(uncomp_buf); - /* Name of field */ - if ( uncomp_buf[0] == MAT_T_INT8 ) { /* Name not in tag */ - if ( mat->byteswap ) - len = Mat_uint32Swap(uncomp_buf + 1); - else - len = uncomp_buf[1]; - nfields = len / fieldname_size; - if ( nfields * fieldname_size % 8 != 0 ) - i = 8 - (nfields * fieldname_size % 8); - else - i = 0; - if ( nfields ) { - char *ptr = (char *)malloc(nfields * fieldname_size + i); - if ( NULL != ptr ) { - err = Inflate(mat, matvar->internal->z, ptr, - (unsigned int)(nfields * fieldname_size + i), &bytesread); - if ( 0 == err ) { - SetFieldNames(matvar, ptr, nfields, fieldname_size); - } else { - matvar->internal->num_fields = nfields; - matvar->internal->fieldnames = NULL; - } - free(ptr); - } - } else { - matvar->internal->num_fields = 0; - matvar->internal->fieldnames = NULL; - } - } else { - len = (uncomp_buf[0] & 0xffff0000) >> 16; - if ( ((uncomp_buf[0] & 0x0000ffff) == MAT_T_INT8) && len > 0 && len <= 4 ) { - /* Name packed in tag */ - nfields = len / fieldname_size; - if ( nfields ) { - SetFieldNames(matvar, (char *)(uncomp_buf + 1), nfields, fieldname_size); - } else { - matvar->internal->num_fields = 0; - matvar->internal->fieldnames = NULL; - } - } else { - nfields = 0; - } - } - - matvar->data_size = sizeof(matvar_t *); - err = Mul(&nelems_x_nfields, nelems, nfields); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return bytesread; - } - err = Mul(&matvar->nbytes, nelems_x_nfields, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return bytesread; - } - if ( !matvar->nbytes ) - return bytesread; - - matvar->data = calloc(nelems_x_nfields, matvar->data_size); - if ( NULL == matvar->data ) { - Mat_Critical("Couldn't allocate memory for the data"); - return bytesread; - } - - fields = (matvar_t **)matvar->data; - for ( i = 0; i < nelems; i++ ) { - size_t k; - for ( k = 0; k < nfields; k++ ) { - fields[i * nfields + k] = Mat_VarCalloc(); - } - } - if ( NULL != matvar->internal->fieldnames ) { - for ( i = 0; i < nelems; i++ ) { - size_t k; - for ( k = 0; k < nfields; k++ ) { - if ( NULL != matvar->internal->fieldnames[k] ) { - fields[i * nfields + k]->name = Mat_strdup(matvar->internal->fieldnames[k]); - } - } - } - } - - for ( i = 0; i < nelems_x_nfields; i++ ) { - mat_uint32_t nBytes; - /* Read variable tag for struct field */ - err = Inflate(mat, matvar->internal->z, uncomp_buf, 8, &bytesread); - if ( err ) { - Mat_VarFree(fields[i]); - fields[i] = NULL; - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - } - nBytes = uncomp_buf[1]; - if ( uncomp_buf[0] != MAT_T_MATRIX ) { - Mat_VarFree(fields[i]); - fields[i] = NULL; - Mat_Critical("fields[%zu], Uncompressed type not MAT_T_MATRIX", i); - break; - } else if ( 0 == nBytes ) { - /* Empty field: Memory optimization */ - free(fields[i]->internal); - fields[i]->internal = NULL; - continue; - } - fields[i]->compression = MAT_COMPRESSION_ZLIB; - err = Inflate(mat, matvar->internal->z, uncomp_buf, 16, &bytesread); - if ( err ) { - Mat_VarFree(fields[i]); - fields[i] = NULL; - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - (void)Mat_uint32Swap(uncomp_buf + 2); - (void)Mat_uint32Swap(uncomp_buf + 3); - } - nBytes -= 16; - /* Array flags */ - if ( uncomp_buf[0] == MAT_T_UINT32 ) { - array_flags = uncomp_buf[2]; - fields[i]->class_type = CLASS_FROM_ARRAY_FLAGS(array_flags); - fields[i]->isComplex = (array_flags & MAT_F_COMPLEX); - fields[i]->isGlobal = (array_flags & MAT_F_GLOBAL); - fields[i]->isLogical = (array_flags & MAT_F_LOGICAL); - if ( fields[i]->class_type == MAT_C_SPARSE ) { - /* Need to find a more appropriate place to store nzmax */ - fields[i]->nbytes = uncomp_buf[3]; - } - } else { - Mat_Critical("Expected MAT_T_UINT32 for array tags, got %d", uncomp_buf[0]); - InflateSkip(mat, matvar->internal->z, nBytes, &bytesread); - } - if ( fields[i]->class_type != MAT_C_OPAQUE ) { - mat_uint32_t *dims = NULL; - int do_clean = 0; - err = InflateRankDims(mat, matvar->internal->z, uncomp_buf, sizeof(uncomp_buf), - &dims, &bytesread); - if ( NULL == dims ) { - dims = uncomp_buf + 2; - } else { - do_clean = 1; - } - if ( err ) { - if ( do_clean ) { - free(dims); - } - Mat_VarFree(fields[i]); - fields[i] = NULL; - break; - } - nBytes -= 8; - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - } - /* Rank and dimension */ - if ( uncomp_buf[0] == MAT_T_INT32 ) { - int j; - size_t size; - fields[i]->rank = uncomp_buf[1]; - nBytes -= fields[i]->rank; - fields[i]->rank /= 4; - if ( 0 == do_clean && fields[i]->rank > 13 ) { - int rank = fields[i]->rank; - fields[i]->rank = 0; - Mat_Critical("%d is not a valid rank", rank); - continue; - } - err = Mul(&size, fields[i]->rank, sizeof(*fields[i]->dims)); - if ( err ) { - if ( do_clean ) { - free(dims); - } - Mat_VarFree(fields[i]); - fields[i] = NULL; - Mat_Critical("Integer multiplication overflow"); - continue; - } - fields[i]->dims = (size_t *)malloc(size); - if ( mat->byteswap ) { - for ( j = 0; j < fields[i]->rank; j++ ) - fields[i]->dims[j] = Mat_uint32Swap(dims + j); - } else { - for ( j = 0; j < fields[i]->rank; j++ ) - fields[i]->dims[j] = dims[j]; - } - if ( fields[i]->rank % 2 != 0 ) - nBytes -= 4; - } - if ( do_clean ) { - free(dims); - } - /* Variable name tag */ - err = Inflate(mat, matvar->internal->z, uncomp_buf, 8, &bytesread); - if ( err ) { - Mat_VarFree(fields[i]); - fields[i] = NULL; - break; - } - nBytes -= 8; - fields[i]->internal->z = (z_streamp)calloc(1, sizeof(z_stream)); - if ( fields[i]->internal->z != NULL ) { - err = inflateCopy(fields[i]->internal->z, matvar->internal->z); - if ( err == Z_OK ) { - fields[i]->internal->datapos = ftell((FILE *)mat->fp); - if ( fields[i]->internal->datapos != -1L ) { - fields[i]->internal->datapos -= matvar->internal->z->avail_in; - if ( fields[i]->class_type == MAT_C_STRUCT ) - bytesread += ReadNextStructField(mat, fields[i]); - else if ( fields[i]->class_type == MAT_C_CELL ) - bytesread += ReadNextCell(mat, fields[i]); - else if ( nBytes <= (1 << MAX_WBITS) ) { - /* Memory optimization: Read data if less in size - than the zlib inflate state (approximately) */ - err = Mat_VarRead5(mat, fields[i]); - fields[i]->internal->data = fields[i]->data; - fields[i]->data = NULL; - } - (void)fseek((FILE *)mat->fp, fields[i]->internal->datapos, SEEK_SET); - } else { - Mat_Critical("Couldn't determine file position"); - } - if ( fields[i]->internal->data != NULL || - fields[i]->class_type == MAT_C_STRUCT || - fields[i]->class_type == MAT_C_CELL ) { - /* Memory optimization: Free inflate state */ - inflateEnd(fields[i]->internal->z); - free(fields[i]->internal->z); - fields[i]->internal->z = NULL; - } - } else { - Mat_Critical("inflateCopy returned error %s", zError(err)); - } - } else { - Mat_Critical("Couldn't allocate memory"); - } - } - InflateSkip(mat, matvar->internal->z, nBytes, &bytesread); - } -#else - Mat_Critical("Not compiled with zlib support"); -#endif - } else { - mat_uint32_t buf[6] = {0, 0, 0, 0, 0, 0}; - mat_uint32_t array_flags, len; - - err = Read(buf, 4, 2, (FILE *)mat->fp, &bytesread); - if ( err ) { - return bytesread; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(buf); - (void)Mat_uint32Swap(buf + 1); - } - if ( (buf[0] & 0x0000ffff) == MAT_T_INT32 && buf[1] > 0 ) { - fieldname_size = buf[1]; - } else { - Mat_Critical("Error getting fieldname size"); - return bytesread; - } - - /* Field name tag */ - err = Read(buf, 4, 2, (FILE *)mat->fp, &bytesread); - if ( err ) { - return bytesread; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(buf); - /* Name of field */ - if ( buf[0] == MAT_T_INT8 ) { /* Name not in tag */ - if ( mat->byteswap ) - len = Mat_uint32Swap(buf + 1); - else - len = buf[1]; - nfields = len / fieldname_size; - if ( nfields ) { - char *ptr = (char *)malloc(nfields * fieldname_size); - if ( NULL != ptr ) { - err = Read(ptr, 1, nfields * fieldname_size, (FILE *)mat->fp, &bytesread); - if ( 0 == err ) { - SetFieldNames(matvar, ptr, nfields, fieldname_size); - } else { - matvar->internal->num_fields = nfields; - matvar->internal->fieldnames = NULL; - } - free(ptr); - } - if ( (nfields * fieldname_size) % 8 ) { - (void)fseek((FILE *)mat->fp, 8 - ((nfields * fieldname_size) % 8), SEEK_CUR); - bytesread += 8 - ((nfields * fieldname_size) % 8); - } - } else { - matvar->internal->num_fields = 0; - matvar->internal->fieldnames = NULL; - } - } else { - len = (buf[0] & 0xffff0000) >> 16; - if ( ((buf[0] & 0x0000ffff) == MAT_T_INT8) && len > 0 && len <= 4 ) { - /* Name packed in tag */ - nfields = len / fieldname_size; - if ( nfields ) { - SetFieldNames(matvar, (char *)(buf + 1), nfields, fieldname_size); - } else { - matvar->internal->num_fields = 0; - matvar->internal->fieldnames = NULL; - } - } else { - nfields = 0; - } - } - - matvar->data_size = sizeof(matvar_t *); - err = Mul(&nelems_x_nfields, nelems, nfields); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return bytesread; - } - err = Mul(&matvar->nbytes, nelems_x_nfields, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return bytesread; - } - if ( !matvar->nbytes ) - return bytesread; - - matvar->data = calloc(nelems_x_nfields, matvar->data_size); - if ( NULL == matvar->data ) { - Mat_Critical("Couldn't allocate memory for the data"); - return bytesread; - } - - fields = (matvar_t **)matvar->data; - for ( i = 0; i < nelems_x_nfields; i++ ) { - mat_uint32_t nBytes; - - fields[i] = Mat_VarCalloc(); - if ( NULL == fields[i] ) { - Mat_Critical("Couldn't allocate memory for field %zu", i); - continue; - } - - /* Read variable tag for struct field */ - err = Read(buf, 4, 2, (FILE *)mat->fp, &bytesread); - if ( err ) { - Mat_VarFree(fields[i]); - fields[i] = NULL; - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(buf); - (void)Mat_uint32Swap(buf + 1); - } - nBytes = buf[1]; - if ( buf[0] != MAT_T_MATRIX ) { - Mat_VarFree(fields[i]); - fields[i] = NULL; - Mat_Critical("fields[%zu] not MAT_T_MATRIX, fpos = %ld", i, ftell((FILE *)mat->fp)); - break; - } else if ( 0 == nBytes ) { - /* Empty field: Memory optimization */ - free(fields[i]->internal); - fields[i]->internal = NULL; - continue; - } - - /* Read array flags and the dimensions tag */ - err = Read(buf, 4, 6, (FILE *)mat->fp, &bytesread); - if ( err ) { - Mat_VarFree(fields[i]); - fields[i] = NULL; - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(buf); - (void)Mat_uint32Swap(buf + 1); - (void)Mat_uint32Swap(buf + 2); - (void)Mat_uint32Swap(buf + 3); - (void)Mat_uint32Swap(buf + 4); - (void)Mat_uint32Swap(buf + 5); - } - nBytes -= 24; - /* Array flags */ - if ( buf[0] == MAT_T_UINT32 ) { - array_flags = buf[2]; - fields[i]->class_type = CLASS_FROM_ARRAY_FLAGS(array_flags); - fields[i]->isComplex = (array_flags & MAT_F_COMPLEX); - fields[i]->isGlobal = (array_flags & MAT_F_GLOBAL); - fields[i]->isLogical = (array_flags & MAT_F_LOGICAL); - if ( fields[i]->class_type == MAT_C_SPARSE ) { - /* Need to find a more appropriate place to store nzmax */ - fields[i]->nbytes = buf[3]; - } - } - /* Rank and dimension */ - { - size_t nbytes = 0; - err = ReadRankDims(mat, fields[i], (enum matio_types)buf[4], buf[5], &nbytes); - bytesread += nbytes; - nBytes -= nbytes; - if ( err ) { - Mat_VarFree(fields[i]); - fields[i] = NULL; - break; - } - } - /* Variable name tag */ - err = Read(buf, 1, 8, (FILE *)mat->fp, &bytesread); - if ( err ) { - Mat_VarFree(fields[i]); - fields[i] = NULL; - break; - } - nBytes -= 8; - fields[i]->internal->datapos = ftell((FILE *)mat->fp); - if ( fields[i]->internal->datapos != -1L ) { - if ( fields[i]->class_type == MAT_C_STRUCT ) - bytesread += ReadNextStructField(mat, fields[i]); - else if ( fields[i]->class_type == MAT_C_CELL ) - bytesread += ReadNextCell(mat, fields[i]); - (void)fseek((FILE *)mat->fp, fields[i]->internal->datapos + nBytes, SEEK_SET); - } else { - Mat_Critical("Couldn't determine file position"); - } - } - - if ( NULL != matvar->internal->fieldnames ) { - for ( i = 0; i < nelems; i++ ) { - size_t k; - for ( k = 0; k < nfields; k++ ) { - if ( NULL != matvar->internal->fieldnames[k] && - NULL != fields[i * nfields + k] ) { - fields[i * nfields + k]->name = Mat_strdup(matvar->internal->fieldnames[k]); - } - } - } - } - } - - return bytesread; -} - -/** @brief Reads the function handle data of the function handle in @c matvar - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar MAT variable pointer - * @return Number of bytes read - */ -static size_t -ReadNextFunctionHandle(mat_t *mat, matvar_t *matvar) -{ - int err; - size_t nelems = 1; - - err = Mat_MulDims(matvar, &nelems); - matvar->data_size = sizeof(matvar_t *); - err |= Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err ) - return 0; - - matvar->data = malloc(matvar->nbytes); - if ( matvar->data != NULL ) { - size_t i; - matvar_t **functions = (matvar_t **)matvar->data; - for ( i = 0; i < nelems; i++ ) { - functions[i] = Mat_VarReadNextInfo(mat); - err = NULL == functions[i]; - if ( err ) - break; - } - if ( err ) { - free(matvar->data); - matvar->data = NULL; - matvar->data_size = 0; - matvar->nbytes = 0; - } - } else { - matvar->data_size = 0; - matvar->nbytes = 0; - } - - return 0; -} - -/** @brief Reads the rank and dimensions in @c matvar - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar MAT variable pointer - * @param data_type data type of dimension array - * @param nbytes len of dimension array in bytes - * @param[out] read_bytes Read bytes - * @retval 0 on success - */ -static int -ReadRankDims(mat_t *mat, matvar_t *matvar, enum matio_types data_type, mat_uint32_t nbytes, - size_t *read_bytes) -{ - int err = MATIO_E_NO_ERROR; - /* Rank and dimension */ - if ( data_type == MAT_T_INT32 ) { - matvar->rank = nbytes / sizeof(mat_uint32_t); - matvar->dims = (size_t *)malloc(matvar->rank * sizeof(*matvar->dims)); - if ( NULL != matvar->dims ) { - int i; - mat_uint32_t buf; - - for ( i = 0; i < matvar->rank; i++ ) { - err = Read(&buf, sizeof(mat_uint32_t), 1, (FILE *)mat->fp, read_bytes); - if ( MATIO_E_NO_ERROR == err ) { - if ( mat->byteswap ) { - matvar->dims[i] = Mat_uint32Swap(&buf); - } else { - matvar->dims[i] = buf; - } - } else { - free(matvar->dims); - matvar->dims = NULL; - matvar->rank = 0; - return err; - } - } - - if ( matvar->rank % 2 != 0 ) { - err = Read(&buf, sizeof(mat_uint32_t), 1, (FILE *)mat->fp, read_bytes); - if ( err ) { - free(matvar->dims); - matvar->dims = NULL; - matvar->rank = 0; - return err; - } - } - } else { - matvar->rank = 0; - err = MATIO_E_OUT_OF_MEMORY; - Mat_Critical("Error allocating memory for dims"); - } - } - return err; -} - -/** @brief Writes the header and data for a given type - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @retval 0 on success - */ -static int -WriteType(mat_t *mat, matvar_t *matvar) -{ - int err; - const mat_uint8_t pad1 = 0; - int nBytes, j; - size_t nelems = 1; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) - return err; - - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: { - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)matvar->data; - - if ( NULL == matvar->data ) - complex_data = &null_complex_data; - - nBytes = WriteData(mat, complex_data->Re, nelems, matvar->data_type); - if ( nBytes % 8 ) - for ( j = nBytes % 8; j < 8; j++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - nBytes = WriteData(mat, complex_data->Im, nelems, matvar->data_type); - if ( nBytes % 8 ) - for ( j = nBytes % 8; j < 8; j++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } else { - nBytes = WriteData(mat, matvar->data, nelems, matvar->data_type); - if ( nBytes % 8 ) - for ( j = nBytes % 8; j < 8; j++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } - break; - } - case MAT_C_CHAR: - if ( matvar->data_type == MAT_T_UTF8 ) { - nelems = matvar->nbytes; - } - nBytes = WriteCharData(mat, matvar->data, nelems, matvar->data_type); - break; - case MAT_C_CELL: { - size_t i; - matvar_t **cells = (matvar_t **)matvar->data; - - /* Check for an empty cell array */ - if ( matvar->nbytes == 0 || matvar->data_size == 0 || matvar->data == NULL ) - break; - nelems = matvar->nbytes / matvar->data_size; - for ( i = 0; i < nelems; i++ ) - WriteCellArrayField(mat, cells[i]); - break; - } - case MAT_C_STRUCT: { - const mat_uint32_t array_name_type = MAT_T_INT8; - const mat_uint32_t fieldname_type = MAT_T_INT32; - const mat_uint32_t fieldname_data_size = 4; - char *padzero; - mat_uint32_t fieldname_size; - size_t maxlen = 0, nfields, i, nelems_x_nfields; - matvar_t **fields = (matvar_t **)matvar->data; - mat_uint32_t fieldname; - - /* nelems*matvar->data_size can be zero when saving a struct that - * contains an empty struct in one of its fields - * (e.g. x.y = struct('z', {})). If it's zero, we would divide - * by zero. - */ - nfields = matvar->internal->num_fields; - /* Check for a structure with no fields */ - if ( nfields < 1 ) { - fieldname = (fieldname_data_size << 16) | fieldname_type; - fwrite(&fieldname, 4, 1, (FILE *)mat->fp); - fieldname_size = 1; - fwrite(&fieldname_size, 4, 1, (FILE *)mat->fp); - fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - nBytes = 0; - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - break; - } - - for ( i = 0; i < nfields; i++ ) { - size_t len = strlen(matvar->internal->fieldnames[i]); - if ( len > maxlen ) - maxlen = len; - } - maxlen++; - fieldname_size = maxlen; - while ( nfields * fieldname_size % 8 != 0 ) - fieldname_size++; - fieldname = (fieldname_data_size << 16) | fieldname_type; - fwrite(&fieldname, 4, 1, (FILE *)mat->fp); - fwrite(&fieldname_size, 4, 1, (FILE *)mat->fp); - fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - nBytes = nfields * fieldname_size; - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - padzero = (char *)calloc(fieldname_size, 1); - for ( i = 0; i < nfields; i++ ) { - size_t len = strlen(matvar->internal->fieldnames[i]); - fwrite(matvar->internal->fieldnames[i], 1, len, (FILE *)mat->fp); - fwrite(padzero, 1, fieldname_size - len, (FILE *)mat->fp); - } - free(padzero); - err = Mul(&nelems_x_nfields, nelems, nfields); - if ( err ) - break; - for ( i = 0; i < nelems_x_nfields; i++ ) - WriteStructField(mat, fields[i]); - break; - } - case MAT_C_SPARSE: { - mat_sparse_t *sparse = (mat_sparse_t *)matvar->data; - - nBytes = WriteData(mat, sparse->ir, sparse->nir, MAT_T_UINT32); - if ( nBytes % 8 ) - for ( j = nBytes % 8; j < 8; j++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - nBytes = WriteData(mat, sparse->jc, sparse->njc, MAT_T_UINT32); - if ( nBytes % 8 ) - for ( j = nBytes % 8; j < 8; j++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)sparse->data; - nBytes = WriteData(mat, complex_data->Re, sparse->ndata, matvar->data_type); - if ( nBytes % 8 ) - for ( j = nBytes % 8; j < 8; j++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - nBytes = WriteData(mat, complex_data->Im, sparse->ndata, matvar->data_type); - if ( nBytes % 8 ) - for ( j = nBytes % 8; j < 8; j++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } else { - nBytes = WriteData(mat, sparse->data, sparse->ndata, matvar->data_type); - if ( nBytes % 8 ) - for ( j = nBytes % 8; j < 8; j++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } - } - case MAT_C_FUNCTION: - case MAT_C_OBJECT: - case MAT_C_EMPTY: - case MAT_C_OPAQUE: - break; - default: - err = MATIO_E_OUTPUT_BAD_DATA; - break; - } - - return err; -} - -/** @brief Writes the header and data for an element of a cell array - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @retval 0 on success - */ -static int -WriteCellArrayField(mat_t *mat, matvar_t *matvar) -{ - mat_uint32_t array_flags, nzmax = 0; - int array_flags_type = MAT_T_UINT32, dims_array_type = MAT_T_INT32; - int array_flags_size = 8, matrix_type = MAT_T_MATRIX; - const mat_uint32_t pad4 = 0; - const mat_uint8_t pad1 = 0; - int nBytes, i; - long start = 0, end = 0; - - if ( matvar == NULL || mat == NULL ) - return MATIO_E_BAD_ARGUMENT; - - fwrite(&matrix_type, 4, 1, (FILE *)mat->fp); - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - if ( MAT_C_EMPTY == matvar->class_type ) { - /* exit early if this is an empty data */ - return MATIO_E_NO_ERROR; - } - start = ftell((FILE *)mat->fp); - - /* Array Flags */ - array_flags = matvar->class_type & CLASS_TYPE_MASK; - if ( matvar->isComplex ) - array_flags |= MAT_F_COMPLEX; - if ( matvar->isGlobal ) - array_flags |= MAT_F_GLOBAL; - if ( matvar->isLogical ) - array_flags |= MAT_F_LOGICAL; - if ( matvar->class_type == MAT_C_SPARSE ) - nzmax = ((mat_sparse_t *)matvar->data)->nzmax; - - if ( mat->byteswap ) - array_flags = Mat_int32Swap((mat_int32_t *)&array_flags); - fwrite(&array_flags_type, 4, 1, (FILE *)mat->fp); - fwrite(&array_flags_size, 4, 1, (FILE *)mat->fp); - fwrite(&array_flags, 4, 1, (FILE *)mat->fp); - fwrite(&nzmax, 4, 1, (FILE *)mat->fp); - /* Rank and Dimension */ - nBytes = matvar->rank * 4; - fwrite(&dims_array_type, 4, 1, (FILE *)mat->fp); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - for ( i = 0; i < matvar->rank; i++ ) { - mat_int32_t dim; - dim = matvar->dims[i]; - fwrite(&dim, 4, 1, (FILE *)mat->fp); - } - if ( matvar->rank % 2 != 0 ) - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - /* Name of variable */ - if ( !matvar->name ) { - const mat_uint32_t array_name_type = MAT_T_INT8; - fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - } else if ( strlen(matvar->name) <= 4 ) { - mat_uint32_t array_name_type = MAT_T_INT8; - const mat_uint32_t array_name_len = (mat_uint32_t)strlen(matvar->name); - array_name_type |= array_name_len << 16; - fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - fwrite(matvar->name, 1, array_name_len, (FILE *)mat->fp); - for ( i = array_name_len; i < 4; i++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } else { - const mat_uint32_t array_name_type = MAT_T_INT8; - const mat_uint32_t array_name_len = (mat_uint32_t)strlen(matvar->name); - fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - fwrite(&array_name_len, 4, 1, (FILE *)mat->fp); - fwrite(matvar->name, 1, array_name_len, (FILE *)mat->fp); - if ( array_name_len % 8 ) - for ( i = array_name_len % 8; i < 8; i++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } - - WriteType(mat, matvar); - end = ftell((FILE *)mat->fp); - if ( start != -1L && end != -1L ) { - nBytes = (int)(end - start); - (void)fseek((FILE *)mat->fp, (long)-(nBytes + 4), SEEK_CUR); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - (void)fseek((FILE *)mat->fp, end, SEEK_SET); - } else { - Mat_Critical("Couldn't determine file position"); - } - - return MATIO_E_NO_ERROR; -} - -#if HAVE_ZLIB -/** @brief Writes the header and data for a given class type - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @return number of bytes written to the MAT file - */ -static size_t -WriteCompressedTypeArrayFlags(mat_t *mat, matvar_t *matvar, z_streamp z) -{ - mat_uint32_t array_flags; - const mat_uint32_t array_name_type = MAT_T_INT8; - int array_flags_type = MAT_T_UINT32, dims_array_type = MAT_T_INT32; - int array_flags_size = 8; - int nBytes, i, nzmax = 0; - - mat_uint32_t comp_buf[512]; - mat_uint32_t uncomp_buf[512]; - int buf_size = 512; - size_t byteswritten = 0; - - if ( MAT_C_EMPTY == matvar->class_type ) { - /* exit early if this is an empty data */ - return byteswritten; - } - - memset(&uncomp_buf, 0, sizeof(uncomp_buf)); - /* Array Flags */ - array_flags = matvar->class_type & CLASS_TYPE_MASK; - if ( matvar->isComplex ) - array_flags |= MAT_F_COMPLEX; - if ( matvar->isGlobal ) - array_flags |= MAT_F_GLOBAL; - if ( matvar->isLogical ) - array_flags |= MAT_F_LOGICAL; - if ( matvar->class_type == MAT_C_SPARSE ) - nzmax = ((mat_sparse_t *)matvar->data)->nzmax; - uncomp_buf[0] = array_flags_type; - uncomp_buf[1] = array_flags_size; - uncomp_buf[2] = array_flags; - uncomp_buf[3] = nzmax; - /* Rank and Dimension */ - nBytes = matvar->rank * 4; - uncomp_buf[4] = dims_array_type; - uncomp_buf[5] = nBytes; - for ( i = 0; i < matvar->rank; i++ ) { - mat_int32_t dim; - dim = matvar->dims[i]; - uncomp_buf[6 + i] = dim; - } - if ( matvar->rank % 2 != 0 ) { - const mat_uint32_t pad4 = 0; - uncomp_buf[6 + i] = pad4; - i++; - } - - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = (6 + i) * sizeof(*uncomp_buf); - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += - fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - /* Name of variable */ - uncomp_buf[0] = array_name_type; - uncomp_buf[1] = 0; - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += - fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - - matvar->internal->datapos = ftell((FILE *)mat->fp); - if ( matvar->internal->datapos == -1L ) { - Mat_Critical("Couldn't determine file position"); - } - - byteswritten += WriteCompressedType(mat, matvar, z); - return byteswritten; -} - -/** @brief Writes the header and data for a given class type - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @return number of bytes written to the MAT file - */ -static size_t -WriteCompressedType(mat_t *mat, matvar_t *matvar, z_streamp z) -{ - int err; - mat_uint32_t comp_buf[512]; - mat_uint32_t uncomp_buf[512]; - size_t byteswritten = 0, nelems = 1; - - if ( MAT_C_EMPTY == matvar->class_type ) { - /* exit early if this is an empty data */ - return byteswritten; - } - - memset(&uncomp_buf, 0, sizeof(uncomp_buf)); - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return byteswritten; - } - - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: { - /* WriteCompressedData makes sure uncompressed data is aligned - * on an 8-byte boundary */ - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)matvar->data; - - if ( NULL == matvar->data ) - complex_data = &null_complex_data; - - byteswritten += - WriteCompressedData(mat, z, complex_data->Re, nelems, matvar->data_type); - byteswritten += - WriteCompressedData(mat, z, complex_data->Im, nelems, matvar->data_type); - } else { - byteswritten += - WriteCompressedData(mat, z, matvar->data, nelems, matvar->data_type); - } - break; - } - case MAT_C_CHAR: { - if ( matvar->data_type == MAT_T_UTF8 ) { - nelems = matvar->nbytes; - } - byteswritten += - WriteCompressedCharData(mat, z, matvar->data, nelems, matvar->data_type); - break; - } - case MAT_C_CELL: { - size_t i; - matvar_t **cells = (matvar_t **)matvar->data; - - /* Check for an empty cell array */ - if ( matvar->nbytes == 0 || matvar->data_size == 0 || matvar->data == NULL ) - break; - nelems = matvar->nbytes / matvar->data_size; - for ( i = 0; i < nelems; i++ ) - WriteCompressedCellArrayField(mat, cells[i], z); - break; - } - case MAT_C_STRUCT: { - int buf_size = 512; - const mat_uint32_t fieldname_type = MAT_T_INT32; - const mat_uint32_t fieldname_data_size = 4; - unsigned char *padzero; - int fieldname_size; - size_t maxlen = 0, nfields, i, nelems_x_nfields; - const mat_uint32_t array_name_type = MAT_T_INT8; - matvar_t **fields = (matvar_t **)matvar->data; - - nfields = matvar->internal->num_fields; - /* Check for a structure with no fields */ - if ( nfields < 1 ) { - fieldname_size = 1; - uncomp_buf[0] = (fieldname_data_size << 16) | fieldname_type; - uncomp_buf[1] = fieldname_size; - uncomp_buf[2] = array_name_type; - uncomp_buf[3] = 0; - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 16; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, - (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - break; - } - - for ( i = 0; i < nfields; i++ ) { - size_t len = strlen(matvar->internal->fieldnames[i]); - if ( len > maxlen ) - maxlen = len; - } - maxlen++; - fieldname_size = maxlen; - while ( nfields * fieldname_size % 8 != 0 ) - fieldname_size++; - uncomp_buf[0] = (fieldname_data_size << 16) | fieldname_type; - uncomp_buf[1] = fieldname_size; - uncomp_buf[2] = array_name_type; - uncomp_buf[3] = nfields * fieldname_size; - - padzero = (unsigned char *)calloc(fieldname_size, 1); - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 16; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, - (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - for ( i = 0; i < nfields; i++ ) { - size_t len = strlen(matvar->internal->fieldnames[i]); - memset(padzero, '\0', fieldname_size); - memcpy(padzero, matvar->internal->fieldnames[i], len); - z->next_in = ZLIB_BYTE_PTR(padzero); - z->avail_in = fieldname_size; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, - (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - } - free(padzero); - err = Mul(&nelems_x_nfields, nelems, nfields); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return byteswritten; - } - for ( i = 0; i < nelems_x_nfields; i++ ) - byteswritten += WriteCompressedStructField(mat, fields[i], z); - break; - } - case MAT_C_SPARSE: { - mat_sparse_t *sparse = (mat_sparse_t *)matvar->data; - - byteswritten += WriteCompressedData(mat, z, sparse->ir, sparse->nir, MAT_T_UINT32); - byteswritten += WriteCompressedData(mat, z, sparse->jc, sparse->njc, MAT_T_UINT32); - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)sparse->data; - byteswritten += - WriteCompressedData(mat, z, complex_data->Re, sparse->ndata, matvar->data_type); - byteswritten += - WriteCompressedData(mat, z, complex_data->Im, sparse->ndata, matvar->data_type); - } else { - byteswritten += - WriteCompressedData(mat, z, sparse->data, sparse->ndata, matvar->data_type); - } - break; - } - case MAT_C_FUNCTION: - case MAT_C_OBJECT: - case MAT_C_EMPTY: - case MAT_C_OPAQUE: - break; - } - - return byteswritten; -} - -/** @brief Writes the header and data for a field of a compressed cell array - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @return number of bytes written to the MAT file - */ -static size_t -WriteCompressedCellArrayField(mat_t *mat, matvar_t *matvar, z_streamp z) -{ - mat_uint32_t comp_buf[512]; - mat_uint32_t uncomp_buf[512]; - int buf_size = 512; - size_t byteswritten = 0, field_buf_size; - - if ( NULL == matvar || NULL == mat || NULL == z ) - return 0; - - memset(&uncomp_buf, 0, sizeof(uncomp_buf)); - uncomp_buf[0] = MAT_T_MATRIX; - if ( MAT_C_EMPTY != matvar->class_type ) { - int err = GetCellArrayFieldBufSize(matvar, &field_buf_size); - if ( err || field_buf_size > UINT32_MAX ) - return 0; - - uncomp_buf[1] = field_buf_size; - } else { - uncomp_buf[1] = 0; - } - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += - fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - - byteswritten += WriteCompressedTypeArrayFlags(mat, matvar, z); - return byteswritten; -} -#endif - -/** @brief Writes the header and data for a field of a struct array - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @retval 0 on success - */ -static int -WriteStructField(mat_t *mat, matvar_t *matvar) -{ - mat_uint32_t array_flags; - const mat_uint32_t array_name_type = MAT_T_INT8; - int array_flags_type = MAT_T_UINT32, dims_array_type = MAT_T_INT32; - int array_flags_size = 8, matrix_type = MAT_T_MATRIX; - const mat_uint32_t pad4 = 0; - int nBytes, i, nzmax = 0; - long start = 0, end = 0; - - if ( mat == NULL ) - return MATIO_E_BAD_ARGUMENT; - - if ( NULL == matvar ) { - size_t dims[2] = {0, 0}; - Mat_WriteEmptyVariable5(mat, NULL, 2, dims); - return MATIO_E_NO_ERROR; - } - - fwrite(&matrix_type, 4, 1, (FILE *)mat->fp); - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - if ( MAT_C_EMPTY == matvar->class_type ) { - /* exit early if this is an empty data */ - return MATIO_E_NO_ERROR; - } - start = ftell((FILE *)mat->fp); - - /* Array Flags */ - array_flags = matvar->class_type & CLASS_TYPE_MASK; - if ( matvar->isComplex ) - array_flags |= MAT_F_COMPLEX; - if ( matvar->isGlobal ) - array_flags |= MAT_F_GLOBAL; - if ( matvar->isLogical ) - array_flags |= MAT_F_LOGICAL; - if ( matvar->class_type == MAT_C_SPARSE ) - nzmax = ((mat_sparse_t *)matvar->data)->nzmax; - - if ( mat->byteswap ) - array_flags = Mat_int32Swap((mat_int32_t *)&array_flags); - fwrite(&array_flags_type, 4, 1, (FILE *)mat->fp); - fwrite(&array_flags_size, 4, 1, (FILE *)mat->fp); - fwrite(&array_flags, 4, 1, (FILE *)mat->fp); - fwrite(&nzmax, 4, 1, (FILE *)mat->fp); - /* Rank and Dimension */ - nBytes = matvar->rank * 4; - fwrite(&dims_array_type, 4, 1, (FILE *)mat->fp); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - for ( i = 0; i < matvar->rank; i++ ) { - mat_int32_t dim; - dim = matvar->dims[i]; - fwrite(&dim, 4, 1, (FILE *)mat->fp); - } - if ( matvar->rank % 2 != 0 ) - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - - /* Name of variable */ - fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - - WriteType(mat, matvar); - end = ftell((FILE *)mat->fp); - if ( start != -1L && end != -1L ) { - nBytes = (int)(end - start); - (void)fseek((FILE *)mat->fp, (long)-(nBytes + 4), SEEK_CUR); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - (void)fseek((FILE *)mat->fp, end, SEEK_SET); - } else { - Mat_Critical("Couldn't determine file position"); - } - - return MATIO_E_NO_ERROR; -} - -#if HAVE_ZLIB -/** @brief Writes the header and data for a field of a compressed struct array - * - * @ingroup mat_internal - * @fixme Currently does not work for cell arrays or sparse data - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @return number of bytes written to the MAT file - */ -static size_t -WriteCompressedStructField(mat_t *mat, matvar_t *matvar, z_streamp z) -{ - mat_uint32_t comp_buf[512]; - mat_uint32_t uncomp_buf[512]; - int buf_size = 512; - size_t byteswritten = 0, field_buf_size; - - if ( NULL == mat || NULL == z ) - return 0; - - if ( NULL == matvar ) { - size_t dims[2] = {0, 0}; - byteswritten = Mat_WriteCompressedEmptyVariable5(mat, NULL, 2, dims, z); - return byteswritten; - } - - memset(&uncomp_buf, 0, sizeof(uncomp_buf)); - uncomp_buf[0] = MAT_T_MATRIX; - if ( MAT_C_EMPTY != matvar->class_type ) { - int err = GetStructFieldBufSize(matvar, &field_buf_size); - if ( err || field_buf_size > UINT32_MAX ) - return 0; - uncomp_buf[1] = field_buf_size; - } else { - uncomp_buf[1] = 0; - } - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += - fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - - byteswritten += WriteCompressedTypeArrayFlags(mat, matvar, z); - return byteswritten; -} -#endif - -static size_t -Mat_WriteEmptyVariable5(mat_t *mat, const char *name, int rank, size_t *dims) -{ - mat_uint32_t array_flags; - mat_uint32_t array_name_type = MAT_T_INT8; - const mat_uint32_t matrix_type = MAT_T_MATRIX; - int array_flags_type = MAT_T_UINT32, dims_array_type = MAT_T_INT32; - int array_flags_size = 8, nBytes, i; - const mat_uint32_t pad4 = 0; - const mat_uint8_t pad1 = 0; - size_t byteswritten = 0; - long start = 0, end = 0; - - fwrite(&matrix_type, 4, 1, (FILE *)mat->fp); - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - start = ftell((FILE *)mat->fp); - - /* Array Flags */ - array_flags = MAT_C_DOUBLE; - - if ( mat->byteswap ) - array_flags = Mat_int32Swap((mat_int32_t *)&array_flags); - byteswritten += fwrite(&array_flags_type, 4, 1, (FILE *)mat->fp); - byteswritten += fwrite(&array_flags_size, 4, 1, (FILE *)mat->fp); - byteswritten += fwrite(&array_flags, 4, 1, (FILE *)mat->fp); - byteswritten += fwrite(&pad4, 4, 1, (FILE *)mat->fp); - /* Rank and Dimension */ - nBytes = rank * 4; - byteswritten += fwrite(&dims_array_type, 4, 1, (FILE *)mat->fp); - byteswritten += fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - for ( i = 0; i < rank; i++ ) { - mat_int32_t dim; - dim = dims[i]; - byteswritten += fwrite(&dim, 4, 1, (FILE *)mat->fp); - } - if ( rank % 2 != 0 ) - byteswritten += fwrite(&pad4, 4, 1, (FILE *)mat->fp); - - if ( NULL == name ) { - /* Name of variable */ - byteswritten += fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - byteswritten += fwrite(&pad4, 4, 1, (FILE *)mat->fp); - } else { - mat_int32_t array_name_len = (mat_int32_t)strlen(name); - /* Name of variable */ - if ( array_name_len <= 4 ) { - array_name_type |= array_name_len << 16; - byteswritten += fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - byteswritten += fwrite(name, 1, array_name_len, (FILE *)mat->fp); - for ( i = array_name_len; i < 4; i++ ) - byteswritten += fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } else { - byteswritten += fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - byteswritten += fwrite(&array_name_len, 4, 1, (FILE *)mat->fp); - byteswritten += fwrite(name, 1, array_name_len, (FILE *)mat->fp); - if ( array_name_len % 8 ) - for ( i = array_name_len % 8; i < 8; i++ ) - byteswritten += fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } - } - - nBytes = WriteData(mat, NULL, 0, MAT_T_DOUBLE); - byteswritten += nBytes; - if ( nBytes % 8 ) - for ( i = nBytes % 8; i < 8; i++ ) - byteswritten += fwrite(&pad1, 1, 1, (FILE *)mat->fp); - - end = ftell((FILE *)mat->fp); - if ( start != -1L && end != -1L ) { - nBytes = (int)(end - start); - (void)fseek((FILE *)mat->fp, (long)-(nBytes + 4), SEEK_CUR); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - (void)fseek((FILE *)mat->fp, end, SEEK_SET); - } else { - Mat_Critical("Couldn't determine file position"); - } - - return byteswritten; -} - -#if HAVE_ZLIB -static size_t -Mat_WriteCompressedEmptyVariable5(mat_t *mat, const char *name, int rank, size_t *dims, z_streamp z) -{ - mat_uint32_t array_flags; - int array_flags_type = MAT_T_UINT32, dims_array_type = MAT_T_INT32; - int array_flags_size = 8; - int i, err; - size_t nBytes, empty_matrix_max_buf_size; - - mat_uint32_t comp_buf[512]; - mat_uint32_t uncomp_buf[512]; - int buf_size = 512; - size_t byteswritten = 0, buf_size_bytes; - - if ( NULL == mat || NULL == z ) - return byteswritten; - - buf_size_bytes = buf_size * sizeof(*comp_buf); - - /* Array Flags */ - array_flags = MAT_C_DOUBLE; - - memset(&uncomp_buf, 0, sizeof(uncomp_buf)); - uncomp_buf[0] = MAT_T_MATRIX; - err = GetEmptyMatrixMaxBufSize(name, rank, &empty_matrix_max_buf_size); - if ( err || empty_matrix_max_buf_size > UINT32_MAX ) - return byteswritten; - uncomp_buf[1] = empty_matrix_max_buf_size; - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size_bytes; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size_bytes - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - uncomp_buf[0] = array_flags_type; - uncomp_buf[1] = array_flags_size; - uncomp_buf[2] = array_flags; - uncomp_buf[3] = 0; - /* Rank and Dimension */ - nBytes = rank * 4; - uncomp_buf[4] = dims_array_type; - uncomp_buf[5] = nBytes; - for ( i = 0; i < rank; i++ ) { - mat_int32_t dim; - dim = dims[i]; - uncomp_buf[6 + i] = dim; - } - if ( rank % 2 != 0 ) { - const mat_uint32_t pad4 = 0; - uncomp_buf[6 + i] = pad4; - i++; - } - - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = (6 + i) * sizeof(*uncomp_buf); - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size_bytes; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size_bytes - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - /* Name of variable */ - if ( NULL == name ) { - const mat_uint32_t array_name_type = MAT_T_INT8; - uncomp_buf[0] = array_name_type; - uncomp_buf[1] = 0; - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size_bytes; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size_bytes - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - } else if ( strlen(name) <= 4 ) { - mat_uint32_t array_name_len = (mat_uint32_t)strlen(name); - const mat_uint32_t array_name_type = MAT_T_INT8; - - memset(uncomp_buf, 0, 8); - uncomp_buf[0] = (array_name_len << 16) | array_name_type; - memcpy(uncomp_buf + 1, name, array_name_len); - if ( array_name_len % 4 ) - array_name_len += 4 - (array_name_len % 4); - - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size_bytes; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size_bytes - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - } else { - mat_uint32_t array_name_len = (mat_uint32_t)strlen(name); - const mat_uint32_t array_name_type = MAT_T_INT8; - - memset(uncomp_buf, 0, buf_size * sizeof(*uncomp_buf)); - uncomp_buf[0] = array_name_type; - uncomp_buf[1] = array_name_len; - memcpy(uncomp_buf + 2, name, array_name_len); - if ( array_name_len % 8 ) - array_name_len += 8 - (array_name_len % 8); - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8 + array_name_len; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size_bytes; - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size_bytes - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - } - - byteswritten += WriteCompressedData(mat, z, NULL, 0, MAT_T_DOUBLE); - return byteswritten; -} -#endif - -/** @if mat_devman - * @brief Reads a data element including tag and data - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar MAT variable pointer - * @param data Pointer to store the data - * @param N number of data elements allocated for the pointer - * @retval 0 on success - * @endif - */ -static int -Mat_VarReadNumeric5(mat_t *mat, matvar_t *matvar, void *data, size_t N) -{ - int nBytes = 0, data_in_tag = 0, err = MATIO_E_NO_ERROR; - enum matio_types packed_type = MAT_T_UNKNOWN; - mat_uint32_t tag[2]; - - if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { -#if HAVE_ZLIB - matvar->internal->z->avail_in = 0; - err = Inflate(mat, matvar->internal->z, tag, 4, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(tag); - - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - nBytes = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - err = Inflate(mat, matvar->internal->z, tag + 1, 4, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(tag + 1); - nBytes = tag[1]; - } -#endif - } else { - err = Read(tag, 4, 1, (FILE *)mat->fp, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(tag); - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - nBytes = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - err = Read(tag + 1, 4, 1, (FILE *)mat->fp, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(tag + 1); - nBytes = tag[1]; - } - } - if ( nBytes == 0 ) { - matvar->nbytes = 0; - return err; - } - - if ( matvar->compression == MAT_COMPRESSION_NONE ) { - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - nBytes = ReadDoubleData(mat, (double *)data, packed_type, N); - break; - case MAT_C_SINGLE: - nBytes = ReadSingleData(mat, (float *)data, packed_type, N); - break; - case MAT_C_INT64: -#ifdef HAVE_MATIO_INT64_T - nBytes = ReadInt64Data(mat, (mat_int64_t *)data, packed_type, N); -#endif - break; - case MAT_C_UINT64: -#ifdef HAVE_MATIO_UINT64_T - nBytes = ReadUInt64Data(mat, (mat_uint64_t *)data, packed_type, N); -#endif - break; - case MAT_C_INT32: - nBytes = ReadInt32Data(mat, (mat_int32_t *)data, packed_type, N); - break; - case MAT_C_UINT32: - nBytes = ReadUInt32Data(mat, (mat_uint32_t *)data, packed_type, N); - break; - case MAT_C_INT16: - nBytes = ReadInt16Data(mat, (mat_int16_t *)data, packed_type, N); - break; - case MAT_C_UINT16: - nBytes = ReadUInt16Data(mat, (mat_uint16_t *)data, packed_type, N); - break; - case MAT_C_INT8: - nBytes = ReadInt8Data(mat, (mat_int8_t *)data, packed_type, N); - break; - case MAT_C_UINT8: - nBytes = ReadUInt8Data(mat, (mat_uint8_t *)data, packed_type, N); - break; - default: - break; - } - nBytes *= Mat_SizeOf(packed_type); - /* - * If the data was in the tag we started on a 4-byte - * boundary so add 4 to make it an 8-byte - */ - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - (void)fseek((FILE *)mat->fp, 8 - (nBytes % 8), SEEK_CUR); -#if HAVE_ZLIB - } else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - nBytes = ReadCompressedDoubleData(mat, matvar->internal->z, (double *)data, - packed_type, N); - break; - case MAT_C_SINGLE: - nBytes = ReadCompressedSingleData(mat, matvar->internal->z, (float *)data, - packed_type, N); - break; - case MAT_C_INT64: -#ifdef HAVE_MATIO_INT64_T - nBytes = ReadCompressedInt64Data(mat, matvar->internal->z, (mat_int64_t *)data, - packed_type, N); -#endif - break; - case MAT_C_UINT64: -#ifdef HAVE_MATIO_UINT64_T - nBytes = ReadCompressedUInt64Data(mat, matvar->internal->z, (mat_uint64_t *)data, - packed_type, N); -#endif - break; - case MAT_C_INT32: - nBytes = ReadCompressedInt32Data(mat, matvar->internal->z, (mat_int32_t *)data, - packed_type, N); - break; - case MAT_C_UINT32: - nBytes = ReadCompressedUInt32Data(mat, matvar->internal->z, (mat_uint32_t *)data, - packed_type, N); - break; - case MAT_C_INT16: - nBytes = ReadCompressedInt16Data(mat, matvar->internal->z, (mat_int16_t *)data, - packed_type, N); - break; - case MAT_C_UINT16: - nBytes = ReadCompressedUInt16Data(mat, matvar->internal->z, (mat_uint16_t *)data, - packed_type, N); - break; - case MAT_C_INT8: - nBytes = ReadCompressedInt8Data(mat, matvar->internal->z, (mat_int8_t *)data, - packed_type, N); - break; - case MAT_C_UINT8: - nBytes = ReadCompressedUInt8Data(mat, matvar->internal->z, (mat_uint8_t *)data, - packed_type, N); - break; - default: - break; - } - /* - * If the data was in the tag we started on a 4-byte - * boundary so add 4 to make it an 8-byte - */ - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - err = InflateSkip(mat, matvar->internal->z, 8 - (nBytes % 8), NULL); -#endif - } - return err; -} - -/** @if mat_devman - * @brief Reads the data of a version 5 MAT variable - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar MAT variable pointer to read the data - * @retval 0 on success - * @endif - */ -static int -Mat_VarRead5(mat_t *mat, matvar_t *matvar) -{ - int nBytes = 0, byteswap, data_in_tag = 0, err; - size_t nelems = 1; - enum matio_types packed_type = MAT_T_UNKNOWN; - long fpos; - mat_uint32_t tag[2]; - size_t bytesread = 0; - - if ( matvar == NULL ) - return MATIO_E_BAD_ARGUMENT; - else if ( matvar->rank == 0 ) /* An empty data set */ - return MATIO_E_NO_ERROR; -#if HAVE_ZLIB - else if ( NULL != matvar->internal->data ) { - /* Data already read in ReadNextStructField or ReadNextCell */ - matvar->data = matvar->internal->data; - matvar->internal->data = NULL; - return MATIO_E_NO_ERROR; - } -#endif - fpos = ftell((FILE *)mat->fp); - if ( fpos == -1L ) { - Mat_Critical("Couldn't determine file position"); - return MATIO_E_GENERIC_READ_ERROR; - } - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - byteswap = mat->byteswap; - switch ( matvar->class_type ) { - case MAT_C_EMPTY: - matvar->nbytes = 0; - matvar->data_size = sizeof(double); - matvar->data_type = MAT_T_DOUBLE; - matvar->rank = 2; - if ( NULL != matvar->dims ) { - free(matvar->dims); - } - matvar->dims = (size_t *)calloc(matvar->rank, sizeof(*(matvar->dims))); - break; - case MAT_C_DOUBLE: - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(double); - matvar->data_type = MAT_T_DOUBLE; - break; - case MAT_C_SINGLE: - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(float); - matvar->data_type = MAT_T_SINGLE; - break; - case MAT_C_INT64: -#ifdef HAVE_MATIO_INT64_T - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(mat_int64_t); - matvar->data_type = MAT_T_INT64; -#endif - break; - case MAT_C_UINT64: -#ifdef HAVE_MATIO_UINT64_T - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(mat_uint64_t); - matvar->data_type = MAT_T_UINT64; -#endif - break; - case MAT_C_INT32: - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(mat_int32_t); - matvar->data_type = MAT_T_INT32; - break; - case MAT_C_UINT32: - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(mat_uint32_t); - matvar->data_type = MAT_T_UINT32; - break; - case MAT_C_INT16: - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(mat_int16_t); - matvar->data_type = MAT_T_INT16; - break; - case MAT_C_UINT16: - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(mat_uint16_t); - matvar->data_type = MAT_T_UINT16; - break; - case MAT_C_INT8: - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(mat_int8_t); - matvar->data_type = MAT_T_INT8; - break; - case MAT_C_UINT8: - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - matvar->data_size = sizeof(mat_uint8_t); - matvar->data_type = MAT_T_UINT8; - break; - case MAT_C_CHAR: - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { -#if HAVE_ZLIB - matvar->internal->z->avail_in = 0; - err = Inflate(mat, matvar->internal->z, tag, 4, &bytesread); - if ( err ) { - break; - } - if ( byteswap ) - (void)Mat_uint32Swap(tag); - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - nBytes = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - err = Inflate(mat, matvar->internal->z, tag + 1, 4, &bytesread); - if ( err ) { - break; - } - if ( byteswap ) - (void)Mat_uint32Swap(tag + 1); - nBytes = tag[1]; - } -#endif - matvar->data_type = packed_type; - matvar->data_size = Mat_SizeOf(matvar->data_type); - matvar->nbytes = nBytes; - } else { - err = Read(tag, 4, 1, (FILE *)mat->fp, &bytesread); - if ( err ) { - break; - } - if ( byteswap ) - (void)Mat_uint32Swap(tag); - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - nBytes = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - err = Read(tag + 1, 4, 1, (FILE *)mat->fp, &bytesread); - if ( err ) { - break; - } - if ( byteswap ) - (void)Mat_uint32Swap(tag + 1); - nBytes = tag[1]; - } - matvar->data_type = packed_type; - matvar->data_size = Mat_SizeOf(matvar->data_type); - matvar->nbytes = nBytes; - } - if ( matvar->isComplex ) { - break; - } - if ( 0 == matvar->nbytes ) { - matvar->data = calloc(1, 1); - } else { - matvar->data = calloc(matvar->nbytes, 1); - } - if ( NULL == matvar->data ) { - err = MATIO_E_OUT_OF_MEMORY; - Mat_Critical("Couldn't allocate memory for the data"); - break; - } - if ( 0 == matvar->nbytes ) { - break; - } - { - size_t nbytes; - err = Mul(&nbytes, nelems, matvar->data_size); - if ( err || nbytes > matvar->nbytes ) { - break; - } - } - if ( matvar->data_type == MAT_T_UTF8 ) { - nelems = matvar->nbytes; - } - if ( matvar->compression == MAT_COMPRESSION_NONE ) { - nBytes = ReadCharData(mat, matvar->data, matvar->data_type, nelems); - /* - * If the data was in the tag we started on a 4-byte - * boundary so add 4 to make it an 8-byte - */ - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - (void)fseek((FILE *)mat->fp, 8 - (nBytes % 8), SEEK_CUR); -#if HAVE_ZLIB - } else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - nBytes = ReadCompressedCharData(mat, matvar->internal->z, matvar->data, - matvar->data_type, nelems); - /* - * If the data was in the tag we started on a 4-byte - * boundary so add 4 to make it an 8-byte - */ - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - InflateSkip(mat, matvar->internal->z, 8 - (nBytes % 8), NULL); -#endif - } - break; - case MAT_C_STRUCT: { - matvar_t **fields; - size_t i, nelems_x_nfields; - - matvar->data_type = MAT_T_STRUCT; - err = Mul(&nelems_x_nfields, nelems, matvar->internal->num_fields); - if ( err || !matvar->nbytes || !matvar->data_size || NULL == matvar->data ) - break; - fields = (matvar_t **)matvar->data; - for ( i = 0; i < nelems_x_nfields; i++ ) { - if ( NULL != fields[i] ) { - err = Mat_VarRead5(mat, fields[i]); - if ( err ) - break; - } - } - break; - } - case MAT_C_CELL: { - matvar_t **cells; - size_t i; - - if ( NULL == matvar->data ) { - Mat_Critical("Data is NULL for cell array %s", matvar->name); - err = MATIO_E_FILE_FORMAT_VIOLATION; - break; - } - cells = (matvar_t **)matvar->data; - for ( i = 0; i < nelems; i++ ) { - if ( NULL != cells[i] ) { - err = Mat_VarRead5(mat, cells[i]); - if ( err ) - break; - } - } - /* FIXME: */ - matvar->data_type = MAT_T_CELL; - break; - } - case MAT_C_SPARSE: { - mat_uint32_t N = 0; - mat_sparse_t *sparse; - - matvar->data_size = sizeof(mat_sparse_t); - matvar->data = calloc(1, matvar->data_size); - if ( matvar->data == NULL ) { - err = MATIO_E_OUT_OF_MEMORY; - Mat_Critical("Mat_VarRead5: Allocation of data pointer failed"); - break; - } - sparse = (mat_sparse_t *)matvar->data; - sparse->nzmax = matvar->nbytes; - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - /* Read ir */ - bytesread += ReadSparse(mat, matvar, &sparse->nir, &sparse->ir); - /* Read jc */ - bytesread += ReadSparse(mat, matvar, &sparse->njc, &sparse->jc); - /* Read data */ - if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { -#if HAVE_ZLIB - matvar->internal->z->avail_in = 0; - err = Inflate(mat, matvar->internal->z, tag, 4, &bytesread); - if ( err ) { - break; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(tag); - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - N = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - (void)ReadCompressedUInt32Data(mat, matvar->internal->z, &N, MAT_T_UINT32, 1); - } -#endif - } else { - err = Read(tag, 4, 1, (FILE *)mat->fp, &bytesread); - if ( err ) { - break; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(tag); - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - N = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - err = Read(&N, 4, 1, (FILE *)mat->fp, &bytesread); - if ( err ) { - break; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(&N); - } - } - if ( matvar->isLogical && packed_type == MAT_T_DOUBLE ) { - /* For some reason, MAT says the data type is a double, - * but it appears to be written as 8-bit unsigned integer. - */ - packed_type = MAT_T_UINT8; - } -#if defined(EXTENDED_SPARSE) - matvar->data_type = packed_type; -#else - matvar->data_type = MAT_T_DOUBLE; -#endif - { - size_t s_type = Mat_SizeOf(packed_type); - if ( s_type == 0 ) - break; - sparse->ndata = N / s_type; - } - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data; - size_t nbytes; - err = Mul(&nbytes, sparse->ndata, Mat_SizeOf(matvar->data_type)); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - break; - } - complex_data = ComplexMalloc(nbytes); - if ( NULL == complex_data ) { - err = MATIO_E_OUT_OF_MEMORY; - Mat_Critical("Couldn't allocate memory for the complex sparse data"); - break; - } - if ( matvar->compression == MAT_COMPRESSION_NONE ) { -#if defined(EXTENDED_SPARSE) - switch ( matvar->data_type ) { - case MAT_T_DOUBLE: - nBytes = ReadDoubleData(mat, (double *)complex_data->Re, packed_type, - sparse->ndata); - break; - case MAT_T_SINGLE: - nBytes = ReadSingleData(mat, (float *)complex_data->Re, packed_type, - sparse->ndata); - break; - case MAT_T_INT64: -#ifdef HAVE_MATIO_INT64_T - nBytes = ReadInt64Data(mat, (mat_int64_t *)complex_data->Re, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_UINT64: -#ifdef HAVE_MATIO_UINT64_T - nBytes = ReadUInt64Data(mat, (mat_uint64_t *)complex_data->Re, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_INT32: - nBytes = ReadInt32Data(mat, (mat_int32_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_UINT32: - nBytes = ReadUInt32Data(mat, (mat_uint32_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_INT16: - nBytes = ReadInt16Data(mat, (mat_int16_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_UINT16: - nBytes = ReadUInt16Data(mat, (mat_uint16_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_INT8: - nBytes = ReadInt8Data(mat, (mat_int8_t *)complex_data->Re, packed_type, - sparse->ndata); - break; - case MAT_T_UINT8: - nBytes = ReadUInt8Data(mat, (mat_uint8_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - default: - break; - } -#else - nBytes = - ReadDoubleData(mat, (double *)complex_data->Re, packed_type, sparse->ndata); -#endif - nBytes *= Mat_SizeOf(packed_type); - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - (void)fseek((FILE *)mat->fp, 8 - (nBytes % 8), SEEK_CUR); - - /* Complex Data Tag */ - err = Read(tag, 4, 1, (FILE *)mat->fp, &bytesread); - if ( err ) { - ComplexFree(complex_data); - break; - } - if ( byteswap ) - (void)Mat_uint32Swap(tag); - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - nBytes = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - err = Read(tag + 1, 4, 1, (FILE *)mat->fp, &bytesread); - if ( err ) { - ComplexFree(complex_data); - break; - } - if ( byteswap ) - (void)Mat_uint32Swap(tag + 1); - nBytes = tag[1]; - } -#if defined(EXTENDED_SPARSE) - switch ( matvar->data_type ) { - case MAT_T_DOUBLE: - nBytes = ReadDoubleData(mat, (double *)complex_data->Im, packed_type, - sparse->ndata); - break; - case MAT_T_SINGLE: - nBytes = ReadSingleData(mat, (float *)complex_data->Im, packed_type, - sparse->ndata); - break; - case MAT_T_INT64: -#ifdef HAVE_MATIO_INT64_T - nBytes = ReadInt64Data(mat, (mat_int64_t *)complex_data->Im, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_UINT64: -#ifdef HAVE_MATIO_UINT64_T - nBytes = ReadUInt64Data(mat, (mat_uint64_t *)complex_data->Im, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_INT32: - nBytes = ReadInt32Data(mat, (mat_int32_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_UINT32: - nBytes = ReadUInt32Data(mat, (mat_uint32_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_INT16: - nBytes = ReadInt16Data(mat, (mat_int16_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_UINT16: - nBytes = ReadUInt16Data(mat, (mat_uint16_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_INT8: - nBytes = ReadInt8Data(mat, (mat_int8_t *)complex_data->Im, packed_type, - sparse->ndata); - break; - case MAT_T_UINT8: - nBytes = ReadUInt8Data(mat, (mat_uint8_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - default: - break; - } -#else /* EXTENDED_SPARSE */ - nBytes = - ReadDoubleData(mat, (double *)complex_data->Im, packed_type, sparse->ndata); -#endif /* EXTENDED_SPARSE */ - nBytes *= Mat_SizeOf(packed_type); - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - (void)fseek((FILE *)mat->fp, 8 - (nBytes % 8), SEEK_CUR); -#if HAVE_ZLIB - } else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { -#if defined(EXTENDED_SPARSE) - switch ( matvar->data_type ) { - case MAT_T_DOUBLE: - nBytes = ReadCompressedDoubleData(mat, matvar->internal->z, - (double *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_SINGLE: - nBytes = ReadCompressedSingleData(mat, matvar->internal->z, - (float *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_INT64: -#ifdef HAVE_MATIO_INT64_T - nBytes = ReadCompressedInt64Data(mat, matvar->internal->z, - (mat_int64_t *)complex_data->Re, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_UINT64: -#ifdef HAVE_MATIO_UINT64_T - nBytes = ReadCompressedUInt64Data(mat, matvar->internal->z, - (mat_uint64_t *)complex_data->Re, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_INT32: - nBytes = ReadCompressedInt32Data(mat, matvar->internal->z, - (mat_int32_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_UINT32: - nBytes = ReadCompressedUInt32Data(mat, matvar->internal->z, - (mat_uint32_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_INT16: - nBytes = ReadCompressedInt16Data(mat, matvar->internal->z, - (mat_int16_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_UINT16: - nBytes = ReadCompressedUInt16Data(mat, matvar->internal->z, - (mat_uint16_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_INT8: - nBytes = ReadCompressedInt8Data(mat, matvar->internal->z, - (mat_int8_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - case MAT_T_UINT8: - nBytes = ReadCompressedUInt8Data(mat, matvar->internal->z, - (mat_uint8_t *)complex_data->Re, - packed_type, sparse->ndata); - break; - default: - break; - } -#else /* EXTENDED_SPARSE */ - nBytes = ReadCompressedDoubleData(mat, matvar->internal->z, - (double *)complex_data->Re, packed_type, - sparse->ndata); -#endif /* EXTENDED_SPARSE */ - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - InflateSkip(mat, matvar->internal->z, 8 - (nBytes % 8), NULL); - - /* Complex Data Tag */ - err = Inflate(mat, matvar->internal->z, tag, 4, NULL); - if ( err ) { - ComplexFree(complex_data); - break; - } - if ( byteswap ) - (void)Mat_uint32Swap(tag); - - packed_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is in the tag */ - data_in_tag = 1; - nBytes = (tag[0] & 0xffff0000) >> 16; - } else { - data_in_tag = 0; - err = Inflate(mat, matvar->internal->z, tag + 1, 4, NULL); - if ( err ) { - ComplexFree(complex_data); - break; - } - if ( byteswap ) - (void)Mat_uint32Swap(tag + 1); - nBytes = tag[1]; - } -#if defined(EXTENDED_SPARSE) - switch ( matvar->data_type ) { - case MAT_T_DOUBLE: - nBytes = ReadCompressedDoubleData(mat, matvar->internal->z, - (double *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_SINGLE: - nBytes = ReadCompressedSingleData(mat, matvar->internal->z, - (float *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_INT64: -#ifdef HAVE_MATIO_INT64_T - nBytes = ReadCompressedInt64Data(mat, matvar->internal->z, - (mat_int64_t *)complex_data->Im, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_UINT64: -#ifdef HAVE_MATIO_UINT64_T - nBytes = ReadCompressedUInt64Data(mat, matvar->internal->z, - (mat_uint64_t *)complex_data->Im, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_INT32: - nBytes = ReadCompressedInt32Data(mat, matvar->internal->z, - (mat_int32_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_UINT32: - nBytes = ReadCompressedUInt32Data(mat, matvar->internal->z, - (mat_uint32_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_INT16: - nBytes = ReadCompressedInt16Data(mat, matvar->internal->z, - (mat_int16_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_UINT16: - nBytes = ReadCompressedUInt16Data(mat, matvar->internal->z, - (mat_uint16_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_INT8: - nBytes = ReadCompressedInt8Data(mat, matvar->internal->z, - (mat_int8_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - case MAT_T_UINT8: - nBytes = ReadCompressedUInt8Data(mat, matvar->internal->z, - (mat_uint8_t *)complex_data->Im, - packed_type, sparse->ndata); - break; - default: - break; - } -#else /* EXTENDED_SPARSE */ - nBytes = ReadCompressedDoubleData(mat, matvar->internal->z, - (double *)complex_data->Im, packed_type, - sparse->ndata); -#endif /* EXTENDED_SPARSE */ - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - err = InflateSkip(mat, matvar->internal->z, 8 - (nBytes % 8), NULL); -#endif /* HAVE_ZLIB */ - } - sparse->data = complex_data; - } else { /* isComplex */ - size_t nbytes; - err = Mul(&nbytes, sparse->ndata, Mat_SizeOf(matvar->data_type)); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - break; - } - sparse->data = malloc(nbytes); - if ( sparse->data == NULL ) { - err = MATIO_E_OUT_OF_MEMORY; - Mat_Critical("Couldn't allocate memory for the sparse data"); - break; - } - if ( matvar->compression == MAT_COMPRESSION_NONE ) { -#if defined(EXTENDED_SPARSE) - switch ( matvar->data_type ) { - case MAT_T_DOUBLE: - nBytes = ReadDoubleData(mat, (double *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_SINGLE: - nBytes = ReadSingleData(mat, (float *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_INT64: -#ifdef HAVE_MATIO_INT64_T - nBytes = ReadInt64Data(mat, (mat_int64_t *)sparse->data, packed_type, - sparse->ndata); -#endif - break; - case MAT_T_UINT64: -#ifdef HAVE_MATIO_UINT64_T - nBytes = ReadUInt64Data(mat, (mat_uint64_t *)sparse->data, packed_type, - sparse->ndata); -#endif - break; - case MAT_T_INT32: - nBytes = ReadInt32Data(mat, (mat_int32_t *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_UINT32: - nBytes = ReadUInt32Data(mat, (mat_uint32_t *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_INT16: - nBytes = ReadInt16Data(mat, (mat_int16_t *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_UINT16: - nBytes = ReadUInt16Data(mat, (mat_uint16_t *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_INT8: - nBytes = ReadInt8Data(mat, (mat_int8_t *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_UINT8: - nBytes = ReadUInt8Data(mat, (mat_uint8_t *)sparse->data, packed_type, - sparse->ndata); - break; - default: - break; - } -#else - nBytes = - ReadDoubleData(mat, (double *)sparse->data, packed_type, sparse->ndata); -#endif - nBytes *= Mat_SizeOf(packed_type); - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - (void)fseek((FILE *)mat->fp, 8 - (nBytes % 8), SEEK_CUR); -#if HAVE_ZLIB - } else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { -#if defined(EXTENDED_SPARSE) - switch ( matvar->data_type ) { - case MAT_T_DOUBLE: - nBytes = ReadCompressedDoubleData(mat, matvar->internal->z, - (double *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_SINGLE: - nBytes = ReadCompressedSingleData(mat, matvar->internal->z, - (float *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_INT64: -#ifdef HAVE_MATIO_INT64_T - nBytes = ReadCompressedInt64Data(mat, matvar->internal->z, - (mat_int64_t *)sparse->data, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_UINT64: -#ifdef HAVE_MATIO_UINT64_T - nBytes = ReadCompressedUInt64Data(mat, matvar->internal->z, - (mat_uint64_t *)sparse->data, - packed_type, sparse->ndata); -#endif - break; - case MAT_T_INT32: - nBytes = ReadCompressedInt32Data(mat, matvar->internal->z, - (mat_int32_t *)sparse->data, - packed_type, sparse->ndata); - break; - case MAT_T_UINT32: - nBytes = ReadCompressedUInt32Data(mat, matvar->internal->z, - (mat_uint32_t *)sparse->data, - packed_type, sparse->ndata); - break; - case MAT_T_INT16: - nBytes = ReadCompressedInt16Data(mat, matvar->internal->z, - (mat_int16_t *)sparse->data, - packed_type, sparse->ndata); - break; - case MAT_T_UINT16: - nBytes = ReadCompressedUInt16Data(mat, matvar->internal->z, - (mat_uint16_t *)sparse->data, - packed_type, sparse->ndata); - break; - case MAT_T_INT8: - nBytes = ReadCompressedInt8Data(mat, matvar->internal->z, - (mat_int8_t *)sparse->data, packed_type, - sparse->ndata); - break; - case MAT_T_UINT8: - nBytes = ReadCompressedUInt8Data(mat, matvar->internal->z, - (mat_uint8_t *)sparse->data, - packed_type, sparse->ndata); - break; - default: - break; - } -#else /* EXTENDED_SPARSE */ - nBytes = - ReadCompressedDoubleData(mat, matvar->internal->z, (double *)sparse->data, - packed_type, sparse->ndata); -#endif /* EXTENDED_SPARSE */ - if ( data_in_tag ) - nBytes += 4; - if ( (nBytes % 8) != 0 ) - err = InflateSkip(mat, matvar->internal->z, 8 - (nBytes % 8), NULL); -#endif /* HAVE_ZLIB */ - } - } - break; - } - case MAT_C_FUNCTION: { - matvar_t **functions; - size_t nfunctions = 0; - - if ( !matvar->nbytes || !matvar->data_size ) - break; - nfunctions = matvar->nbytes / matvar->data_size; - functions = (matvar_t **)matvar->data; - if ( NULL != functions ) { - size_t i; - for ( i = 0; i < nfunctions; i++ ) { - err = Mat_VarRead5(mat, functions[i]); - if ( err ) - break; - } - } - /* FIXME: */ - matvar->data_type = MAT_T_FUNCTION; - break; - } - case MAT_C_OBJECT: - Mat_Warning("Mat_VarRead5: %d is not a supported class", matvar->class_type); - break; - default: - err = MATIO_E_OPERATION_NOT_SUPPORTED; - Mat_Critical("Mat_VarRead5: %d is not a supported class", matvar->class_type); - break; - } - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: -#endif -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: -#endif - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data; - - err = Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - break; - } - - complex_data = ComplexMalloc(matvar->nbytes); - if ( NULL == complex_data ) { - err = MATIO_E_OUT_OF_MEMORY; - Mat_Critical("Couldn't allocate memory for the complex data"); - break; - } - - err = Mat_VarReadNumeric5(mat, matvar, complex_data->Re, nelems); - if ( err ) { - ComplexFree(complex_data); - break; - } - err = Mat_VarReadNumeric5(mat, matvar, complex_data->Im, nelems); - if ( err ) { - ComplexFree(complex_data); - break; - } - matvar->data = complex_data; - } else { - void *data; - err = Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - break; - } - - data = malloc(matvar->nbytes); - if ( NULL == data ) { - err = MATIO_E_OUT_OF_MEMORY; - Mat_Critical("Couldn't allocate memory for the data"); - break; - } - err = Mat_VarReadNumeric5(mat, matvar, data, nelems); - if ( err ) { - free(data); - break; - } - matvar->data = data; - } - default: - break; - } - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - - return err; -} - -#if HAVE_ZLIB -#define GET_DATA_SLABN_RANK_LOOP \ - do { \ - for ( j = 1; j < rank; j++ ) { \ - cnt[j]++; \ - if ( (cnt[j] % edge[j]) == 0 ) { \ - cnt[j] = 0; \ - if ( (I % dimp[j]) != 0 ) { \ - ptr_in += dimp[j] - (I % dimp[j]) + dimp[j - 1] * start[j]; \ - I += dimp[j] - (I % dimp[j]) + dimp[j - 1] * start[j]; \ - } else if ( start[j] ) { \ - ptr_in += dimp[j - 1] * start[j]; \ - I += dimp[j - 1] * start[j]; \ - } \ - } else { \ - I += inc[j]; \ - ptr_in += inc[j]; \ - break; \ - } \ - } \ - } while ( 0 ) - -#define GET_DATA_SLAB2(T) \ - do { \ - ptr_in += start[1] * dims[0] + start[0]; \ - for ( i = 0; i < edge[1]; i++ ) { \ - for ( j = 0; j < edge[0]; j++ ) { \ - *ptr = (T)(*(ptr_in + j * stride[0])); \ - ptr++; \ - } \ - ptr_in += stride[1] * dims[0]; \ - } \ - } while ( 0 ) - -#define GET_DATA_SLABN(T) \ - do { \ - inc[0] = stride[0] - 1; \ - dimp[0] = dims[0]; \ - N = edge[0]; \ - I = 0; /* start[0]; */ \ - for ( i = 1; i < rank; i++ ) { \ - inc[i] = stride[i] - 1; \ - dimp[i] = dims[i - 1]; \ - for ( j = i; j--; ) { \ - inc[i] *= dims[j]; \ - dimp[i] *= dims[j + 1]; \ - } \ - N *= edge[i]; \ - I += dimp[i - 1] * start[i]; \ - } \ - ptr_in += I; \ - if ( stride[0] == 1 ) { \ - for ( i = 0; i < N; i += edge[0] ) { \ - int k; \ - if ( start[0] ) { \ - ptr_in += start[0]; \ - I += start[0]; \ - } \ - for ( k = 0; k < edge[0]; k++ ) { \ - *(ptr + i + k) = (T)(*(ptr_in + k)); \ - } \ - I += dims[0] - start[0]; \ - ptr_in += dims[0] - start[0]; \ - GET_DATA_SLABN_RANK_LOOP; \ - } \ - } else { \ - for ( i = 0; i < N; i += edge[0] ) { \ - if ( start[0] ) { \ - ptr_in += start[0]; \ - I += start[0]; \ - } \ - for ( j = 0; j < edge[0]; j++ ) { \ - *(ptr + i + j) = (T)(*ptr_in); \ - ptr_in += stride[0]; \ - I += stride[0]; \ - } \ - I += dims[0] - (ptrdiff_t)edge[0] * stride[0] - start[0]; \ - ptr_in += dims[0] - (ptrdiff_t)edge[0] * stride[0] - start[0]; \ - GET_DATA_SLABN_RANK_LOOP; \ - } \ - } \ - } while ( 0 ) - -#ifdef HAVE_MATIO_INT64_T -#define GET_DATA_SLAB2_INT64(T) \ - do { \ - if ( MAT_T_INT64 == data_type ) { \ - mat_int64_t *ptr_in = (mat_int64_t *)data_in; \ - GET_DATA_SLAB2(T); \ - err = MATIO_E_NO_ERROR; \ - } \ - } while ( 0 ) -#else -#define GET_DATA_SLAB2_INT64(T) -#endif /* HAVE_MATIO_INT64_T */ - -#ifdef HAVE_MATIO_UINT64_T -#define GET_DATA_SLAB2_UINT64(T) \ - do { \ - if ( MAT_T_UINT64 == data_type ) { \ - mat_uint64_t *ptr_in = (mat_uint64_t *)data_in; \ - GET_DATA_SLAB2(T); \ - err = MATIO_E_NO_ERROR; \ - } \ - } while ( 0 ) -#else -#define GET_DATA_SLAB2_UINT64(T) -#endif /* HAVE_MATIO_UINT64_T */ - -#define GET_DATA_SLAB2_TYPE(T) \ - do { \ - switch ( data_type ) { \ - case MAT_T_DOUBLE: { \ - double *ptr_in = (double *)data_in; \ - GET_DATA_SLAB2(T); \ - break; \ - } \ - case MAT_T_SINGLE: { \ - float *ptr_in = (float *)data_in; \ - GET_DATA_SLAB2(T); \ - break; \ - } \ - case MAT_T_INT32: { \ - mat_int32_t *ptr_in = (mat_int32_t *)data_in; \ - GET_DATA_SLAB2(T); \ - break; \ - } \ - case MAT_T_UINT32: { \ - mat_uint32_t *ptr_in = (mat_uint32_t *)data_in; \ - GET_DATA_SLAB2(T); \ - break; \ - } \ - case MAT_T_INT16: { \ - mat_int16_t *ptr_in = (mat_int16_t *)data_in; \ - GET_DATA_SLAB2(T); \ - break; \ - } \ - case MAT_T_UINT16: { \ - mat_uint16_t *ptr_in = (mat_uint16_t *)data_in; \ - GET_DATA_SLAB2(T); \ - break; \ - } \ - case MAT_T_INT8: { \ - mat_int8_t *ptr_in = (mat_int8_t *)data_in; \ - GET_DATA_SLAB2(T); \ - break; \ - } \ - case MAT_T_UINT8: { \ - mat_uint8_t *ptr_in = (mat_uint8_t *)data_in; \ - GET_DATA_SLAB2(T); \ - break; \ - } \ - default: \ - err = MATIO_E_OPERATION_NOT_SUPPORTED; \ - GET_DATA_SLAB2_INT64(T); \ - GET_DATA_SLAB2_UINT64(T); \ - break; \ - } \ - } while ( 0 ) - -#ifdef HAVE_MATIO_INT64_T -#define GET_DATA_SLABN_INT64(T) \ - do { \ - if ( MAT_T_INT64 == data_type ) { \ - mat_int64_t *ptr_in = (mat_int64_t *)data_in; \ - GET_DATA_SLABN(T); \ - err = MATIO_E_NO_ERROR; \ - } \ - } while ( 0 ) -#else -#define GET_DATA_SLABN_INT64(T) -#endif /* HAVE_MATIO_INT64_T */ - -#ifdef HAVE_MATIO_UINT64_T -#define GET_DATA_SLABN_UINT64(T) \ - do { \ - if ( MAT_T_UINT64 == data_type ) { \ - mat_uint64_t *ptr_in = (mat_uint64_t *)data_in; \ - GET_DATA_SLABN(T); \ - err = 0; \ - } \ - } while ( 0 ) -#else -#define GET_DATA_SLABN_UINT64(T) -#endif /* HAVE_MATIO_UINT64_T */ - -#define GET_DATA_SLABN_TYPE(T) \ - do { \ - switch ( data_type ) { \ - case MAT_T_DOUBLE: { \ - double *ptr_in = (double *)data_in; \ - GET_DATA_SLABN(T); \ - break; \ - } \ - case MAT_T_SINGLE: { \ - float *ptr_in = (float *)data_in; \ - GET_DATA_SLABN(T); \ - break; \ - } \ - case MAT_T_INT32: { \ - mat_int32_t *ptr_in = (mat_int32_t *)data_in; \ - GET_DATA_SLABN(T); \ - break; \ - } \ - case MAT_T_UINT32: { \ - mat_uint32_t *ptr_in = (mat_uint32_t *)data_in; \ - GET_DATA_SLABN(T); \ - break; \ - } \ - case MAT_T_INT16: { \ - mat_int16_t *ptr_in = (mat_int16_t *)data_in; \ - GET_DATA_SLABN(T); \ - break; \ - } \ - case MAT_T_UINT16: { \ - mat_uint16_t *ptr_in = (mat_uint16_t *)data_in; \ - GET_DATA_SLABN(T); \ - break; \ - } \ - case MAT_T_INT8: { \ - mat_int8_t *ptr_in = (mat_int8_t *)data_in; \ - GET_DATA_SLABN(T); \ - break; \ - } \ - case MAT_T_UINT8: { \ - mat_uint8_t *ptr_in = (mat_uint8_t *)data_in; \ - GET_DATA_SLABN(T); \ - break; \ - } \ - default: \ - err = MATIO_E_OPERATION_NOT_SUPPORTED; \ - GET_DATA_SLABN_INT64(T); \ - GET_DATA_SLABN_UINT64(T); \ - break; \ - } \ - } while ( 0 ) - -static int -GetDataSlab(void *data_in, void *data_out, enum matio_classes class_type, - enum matio_types data_type, size_t *dims, int *start, int *stride, int *edge, int rank, - size_t nbytes) -{ - int err = MATIO_E_NO_ERROR; - int same_type = 0; - if ( (class_type == MAT_C_DOUBLE && data_type == MAT_T_DOUBLE) || - (class_type == MAT_C_SINGLE && data_type == MAT_T_SINGLE) || - (class_type == MAT_C_INT16 && data_type == MAT_T_INT16) || - (class_type == MAT_C_INT32 && data_type == MAT_T_INT32) || - (class_type == MAT_C_INT64 && data_type == MAT_T_INT64) || - (class_type == MAT_C_INT8 && data_type == MAT_T_INT8) || - (class_type == MAT_C_UINT16 && data_type == MAT_T_UINT16) || - (class_type == MAT_C_UINT32 && data_type == MAT_T_UINT32) || - (class_type == MAT_C_UINT64 && data_type == MAT_T_UINT64) || - (class_type == MAT_C_UINT8 && data_type == MAT_T_UINT8) ) - same_type = 1; - - if ( rank == 2 ) { - if ( (size_t)stride[0] * (edge[0] - 1) + start[0] + 1 > dims[0] ) - err = MATIO_E_BAD_ARGUMENT; - else if ( (size_t)stride[1] * (edge[1] - 1) + start[1] + 1 > dims[1] ) - err = MATIO_E_BAD_ARGUMENT; - else if ( (stride[0] == 1 && (size_t)edge[0] == dims[0]) && (stride[1] == 1) && - (same_type == 1) ) - memcpy(data_out, data_in, nbytes); - else { - int i, j; - - switch ( class_type ) { - case MAT_C_DOUBLE: { - double *ptr = (double *)data_out; - GET_DATA_SLAB2_TYPE(double); - break; - } - case MAT_C_SINGLE: { - float *ptr = (float *)data_out; - GET_DATA_SLAB2_TYPE(float); - break; - } -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: { - mat_int64_t *ptr = (mat_int64_t *)data_out; - GET_DATA_SLAB2_TYPE(mat_int64_t); - break; - } -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: { - mat_uint64_t *ptr = (mat_uint64_t *)data_out; - GET_DATA_SLAB2_TYPE(mat_uint64_t); - break; - } -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_C_INT32: { - mat_int32_t *ptr = (mat_int32_t *)data_out; - GET_DATA_SLAB2_TYPE(mat_int32_t); - break; - } - case MAT_C_UINT32: { - mat_uint32_t *ptr = (mat_uint32_t *)data_out; - GET_DATA_SLAB2_TYPE(mat_uint32_t); - break; - } - case MAT_C_INT16: { - mat_int16_t *ptr = (mat_int16_t *)data_out; - GET_DATA_SLAB2_TYPE(mat_int16_t); - break; - } - case MAT_C_UINT16: { - mat_uint16_t *ptr = (mat_uint16_t *)data_out; - GET_DATA_SLAB2_TYPE(mat_uint16_t); - break; - } - case MAT_C_INT8: { - mat_int8_t *ptr = (mat_int8_t *)data_out; - GET_DATA_SLAB2_TYPE(mat_int8_t); - break; - } - case MAT_C_UINT8: { - mat_uint8_t *ptr = (mat_uint8_t *)data_out; - GET_DATA_SLAB2_TYPE(mat_uint8_t); - break; - } - default: - err = MATIO_E_OPERATION_NOT_SUPPORTED; - break; - } - } - } else { - int i, j, N, I = 0; - int inc[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int cnt[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int dimp[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - switch ( class_type ) { - case MAT_C_DOUBLE: { - double *ptr = (double *)data_out; - GET_DATA_SLABN_TYPE(double); - break; - } - case MAT_C_SINGLE: { - float *ptr = (float *)data_out; - GET_DATA_SLABN_TYPE(float); - break; - } -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: { - mat_int64_t *ptr = (mat_int64_t *)data_out; - GET_DATA_SLABN_TYPE(mat_int64_t); - break; - } -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: { - mat_uint64_t *ptr = (mat_uint64_t *)data_out; - GET_DATA_SLABN_TYPE(mat_uint64_t); - break; - } -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_C_INT32: { - mat_int32_t *ptr = (mat_int32_t *)data_out; - GET_DATA_SLABN_TYPE(mat_int32_t); - break; - } - case MAT_C_UINT32: { - mat_uint32_t *ptr = (mat_uint32_t *)data_out; - GET_DATA_SLABN_TYPE(mat_uint32_t); - break; - } - case MAT_C_INT16: { - mat_int16_t *ptr = (mat_int16_t *)data_out; - GET_DATA_SLABN_TYPE(mat_int16_t); - break; - } - case MAT_C_UINT16: { - mat_uint16_t *ptr = (mat_uint16_t *)data_out; - GET_DATA_SLABN_TYPE(mat_uint16_t); - break; - } - case MAT_C_INT8: { - mat_int8_t *ptr = (mat_int8_t *)data_out; - GET_DATA_SLABN_TYPE(mat_int8_t); - break; - } - case MAT_C_UINT8: { - mat_uint8_t *ptr = (mat_uint8_t *)data_out; - GET_DATA_SLABN_TYPE(mat_uint8_t); - break; - } - default: - err = MATIO_E_OPERATION_NOT_SUPPORTED; - break; - } - } - - return err; -} - -#undef GET_DATA_SLAB2 -#undef GET_DATA_SLAB2_TYPE -#undef GET_DATA_SLAB2_INT64 -#undef GET_DATA_SLAB2_UINT64 -#undef GET_DATA_SLABN -#undef GET_DATA_SLABN_TYPE -#undef GET_DATA_SLABN_INT64 -#undef GET_DATA_SLABN_UINT64 -#undef GET_DATA_SLABN_RANK_LOOP - -#define GET_DATA_LINEAR \ - do { \ - ptr_in += start; \ - if ( !stride ) { \ - memcpy(ptr, ptr_in, (size_t)edge *data_size); \ - } else { \ - int i; \ - for ( i = 0; i < edge; i++ ) \ - memcpy(ptr++, ptr_in + i * stride, data_size); \ - } \ - } while ( 0 ) - -static int -GetDataLinear(void *data_in, void *data_out, enum matio_classes class_type, - enum matio_types data_type, int start, int stride, int edge) -{ - int err = MATIO_E_NO_ERROR; - size_t data_size = Mat_SizeOf(data_type); - - switch ( class_type ) { - case MAT_C_DOUBLE: { - double *ptr = (double *)data_out; - double *ptr_in = (double *)data_in; - GET_DATA_LINEAR; - break; - } - case MAT_C_SINGLE: { - float *ptr = (float *)data_out; - float *ptr_in = (float *)data_in; - GET_DATA_LINEAR; - break; - } -#ifdef HAVE_MATIO_INT64_T - case MAT_C_INT64: { - mat_int64_t *ptr = (mat_int64_t *)data_out; - mat_int64_t *ptr_in = (mat_int64_t *)data_in; - GET_DATA_LINEAR; - break; - } -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_C_UINT64: { - mat_uint64_t *ptr = (mat_uint64_t *)data_out; - mat_uint64_t *ptr_in = (mat_uint64_t *)data_in; - GET_DATA_LINEAR; - break; - } -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_C_INT32: { - mat_int32_t *ptr = (mat_int32_t *)data_out; - mat_int32_t *ptr_in = (mat_int32_t *)data_in; - GET_DATA_LINEAR; - break; - } - case MAT_C_UINT32: { - mat_uint32_t *ptr = (mat_uint32_t *)data_out; - mat_uint32_t *ptr_in = (mat_uint32_t *)data_in; - GET_DATA_LINEAR; - break; - } - case MAT_C_INT16: { - mat_int16_t *ptr = (mat_int16_t *)data_out; - mat_int16_t *ptr_in = (mat_int16_t *)data_in; - GET_DATA_LINEAR; - break; - } - case MAT_C_UINT16: { - mat_uint16_t *ptr = (mat_uint16_t *)data_out; - mat_uint16_t *ptr_in = (mat_uint16_t *)data_in; - GET_DATA_LINEAR; - break; - } - case MAT_C_INT8: { - mat_int8_t *ptr = (mat_int8_t *)data_out; - mat_int8_t *ptr_in = (mat_int8_t *)data_in; - GET_DATA_LINEAR; - break; - } - case MAT_C_UINT8: { - mat_uint8_t *ptr = (mat_uint8_t *)data_out; - mat_uint8_t *ptr_in = (mat_uint8_t *)data_in; - GET_DATA_LINEAR; - break; - } - default: - err = MATIO_E_OPERATION_NOT_SUPPORTED; - break; - } - - return err; -} - -#undef GET_DATA_LINEAR -#endif - -/** @if mat_devman - * @brief Reads a slab of data from the mat variable @c matvar - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @param data pointer to store the read data in (must be of size - * edge[0]*...edge[rank-1]*Mat_SizeOfClass(matvar->class_type)) - * @param start index to start reading data in each dimension - * @param stride write data every @c stride elements in each dimension - * @param edge number of elements to read in each dimension - * @retval 0 on success - * @endif - */ -static int -Mat_VarReadData5(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, int *edge) -{ - int err = MATIO_E_NO_ERROR, real_bytes = 0; - mat_int32_t tag[2]; -#if HAVE_ZLIB - z_stream z; -#endif - - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - if ( matvar->compression == MAT_COMPRESSION_NONE ) { - err = Read(tag, 4, 2, (FILE *)mat->fp, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - (void)Mat_int32Swap(tag + 1); - } - matvar->data_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is packed in the tag */ - (void)fseek((FILE *)mat->fp, -4, SEEK_CUR); - real_bytes = 4 + (tag[0] >> 16); - } else { - real_bytes = 8 + tag[1]; - } -#if HAVE_ZLIB - } else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - if ( NULL != matvar->internal->data ) { - /* Data already read in ReadNextStructField or ReadNextCell */ - if ( matvar->isComplex ) { - mat_complex_split_t *ci, *co; - - co = (mat_complex_split_t *)data; - ci = (mat_complex_split_t *)matvar->internal->data; - err = GetDataSlab(ci->Re, co->Re, matvar->class_type, matvar->data_type, - matvar->dims, start, stride, edge, matvar->rank, matvar->nbytes); - if ( MATIO_E_NO_ERROR == err ) - err = GetDataSlab(ci->Im, co->Im, matvar->class_type, matvar->data_type, - matvar->dims, start, stride, edge, matvar->rank, - matvar->nbytes); - return err; - } else { - return GetDataSlab(matvar->internal->data, data, matvar->class_type, - matvar->data_type, matvar->dims, start, stride, edge, - matvar->rank, matvar->nbytes); - } - } - - err = inflateCopy(&z, matvar->internal->z); - if ( err != Z_OK ) { - Mat_Critical("inflateCopy returned error %s", zError(err)); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - z.avail_in = 0; - err = Inflate(mat, &z, tag, 4, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - } - matvar->data_type = TYPE_FROM_TAG(tag[0]); - if ( !(tag[0] & 0xffff0000) ) { /* Data is NOT packed in the tag */ - err = Inflate(mat, &z, tag + 1, 4, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag + 1); - } - real_bytes = 8 + tag[1]; - } else { - real_bytes = 4 + (tag[0] >> 16); - } -#endif - } - if ( real_bytes % 8 ) - real_bytes += (8 - (real_bytes % 8)); - - if ( matvar->rank == 2 ) { - if ( (size_t)stride[0] * (edge[0] - 1) + start[0] + 1 > matvar->dims[0] ) - err = MATIO_E_BAD_ARGUMENT; - else if ( (size_t)stride[1] * (edge[1] - 1) + start[1] + 1 > matvar->dims[1] ) - err = MATIO_E_BAD_ARGUMENT; - else if ( matvar->compression == MAT_COMPRESSION_NONE ) { - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)data; - - ReadDataSlab2(mat, complex_data->Re, matvar->class_type, matvar->data_type, - matvar->dims, start, stride, edge); - (void)fseek((FILE *)mat->fp, matvar->internal->datapos + real_bytes, SEEK_SET); - err = Read(tag, 4, 2, (FILE *)mat->fp, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - (void)Mat_int32Swap(tag + 1); - } - matvar->data_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is packed in the tag */ - (void)fseek((FILE *)mat->fp, -4, SEEK_CUR); - } - ReadDataSlab2(mat, complex_data->Im, matvar->class_type, matvar->data_type, - matvar->dims, start, stride, edge); - } else { - ReadDataSlab2(mat, data, matvar->class_type, matvar->data_type, matvar->dims, start, - stride, edge); - } - } -#if HAVE_ZLIB - else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)data; - - ReadCompressedDataSlab2(mat, &z, complex_data->Re, matvar->class_type, - matvar->data_type, matvar->dims, start, stride, edge); - - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - - /* Reset zlib knowledge to before reading real tag */ - inflateEnd(&z); - err = inflateCopy(&z, matvar->internal->z); - if ( err != Z_OK ) { - Mat_Critical("inflateCopy returned error %s", zError(err)); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - InflateSkip(mat, &z, real_bytes, NULL); - z.avail_in = 0; - err = Inflate(mat, &z, tag, 4, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - } - matvar->data_type = TYPE_FROM_TAG(tag[0]); - if ( !(tag[0] & 0xffff0000) ) { /*Data is NOT packed in the tag*/ - InflateSkip(mat, &z, 4, NULL); - } - ReadCompressedDataSlab2(mat, &z, complex_data->Im, matvar->class_type, - matvar->data_type, matvar->dims, start, stride, edge); - } else { - ReadCompressedDataSlab2(mat, &z, data, matvar->class_type, matvar->data_type, - matvar->dims, start, stride, edge); - } - inflateEnd(&z); - } -#endif - } else { - if ( matvar->compression == MAT_COMPRESSION_NONE ) { - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)data; - - ReadDataSlabN(mat, complex_data->Re, matvar->class_type, matvar->data_type, - matvar->rank, matvar->dims, start, stride, edge); - - (void)fseek((FILE *)mat->fp, matvar->internal->datapos + real_bytes, SEEK_SET); - err = Read(tag, 4, 2, (FILE *)mat->fp, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - (void)Mat_int32Swap(tag + 1); - } - matvar->data_type = TYPE_FROM_TAG(tag[0]); - if ( tag[0] & 0xffff0000 ) { /* Data is packed in the tag */ - (void)fseek((FILE *)mat->fp, -4, SEEK_CUR); - } - ReadDataSlabN(mat, complex_data->Im, matvar->class_type, matvar->data_type, - matvar->rank, matvar->dims, start, stride, edge); - } else { - ReadDataSlabN(mat, data, matvar->class_type, matvar->data_type, matvar->rank, - matvar->dims, start, stride, edge); - } - } -#if HAVE_ZLIB - else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)data; - - ReadCompressedDataSlabN(mat, &z, complex_data->Re, matvar->class_type, - matvar->data_type, matvar->rank, matvar->dims, start, - stride, edge); - - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - /* Reset zlib knowledge to before reading real tag */ - inflateEnd(&z); - err = inflateCopy(&z, matvar->internal->z); - if ( err != Z_OK ) { - Mat_Critical("inflateCopy returned error %s", zError(err)); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - InflateSkip(mat, &z, real_bytes, NULL); - z.avail_in = 0; - err = Inflate(mat, &z, tag, 4, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - } - matvar->data_type = TYPE_FROM_TAG(tag[0]); - if ( !(tag[0] & 0xffff0000) ) { /*Data is NOT packed in the tag*/ - InflateSkip(mat, &z, 4, NULL); - } - ReadCompressedDataSlabN(mat, &z, complex_data->Im, matvar->class_type, - matvar->data_type, matvar->rank, matvar->dims, start, - stride, edge); - } else { - ReadCompressedDataSlabN(mat, &z, data, matvar->class_type, matvar->data_type, - matvar->rank, matvar->dims, start, stride, edge); - } - inflateEnd(&z); - } -#endif - } - if ( err == MATIO_E_NO_ERROR ) { - matvar->data_type = ClassType2DataType(matvar->class_type); - matvar->data_size = Mat_SizeOfClass(matvar->class_type); - } - return err; -} - -/** @brief Reads a subset of a MAT variable using a 1-D indexing - * - * Reads data from a MAT variable using a linear (1-D) indexing mode. The - * variable must have been read by Mat_VarReadInfo. - * @ingroup MAT - * @param mat MAT file to read data from - * @param matvar MAT variable information - * @param data pointer to store data in (must be pre-allocated) - * @param start starting index - * @param stride stride of data - * @param edge number of elements to read - * @retval 0 on success - */ -static int -Mat_VarReadDataLinear5(mat_t *mat, matvar_t *matvar, void *data, int start, int stride, int edge) -{ - int err = MATIO_E_NO_ERROR, real_bytes = 0; - mat_int32_t tag[2]; -#if HAVE_ZLIB - z_stream z; -#endif - size_t nelems = 1; - - if ( mat->version == MAT_FT_MAT4 ) - return -1; - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - if ( matvar->compression == MAT_COMPRESSION_NONE ) { - err = Read(tag, 4, 2, (FILE *)mat->fp, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - (void)Mat_int32Swap(tag + 1); - } - matvar->data_type = (enum matio_types)(tag[0] & 0x000000ff); - if ( tag[0] & 0xffff0000 ) { /* Data is packed in the tag */ - (void)fseek((FILE *)mat->fp, -4, SEEK_CUR); - real_bytes = 4 + (tag[0] >> 16); - } else { - real_bytes = 8 + tag[1]; - } -#if HAVE_ZLIB - } else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - if ( NULL != matvar->internal->data ) { - /* Data already read in ReadNextStructField or ReadNextCell */ - if ( matvar->isComplex ) { - mat_complex_split_t *ci, *co; - - co = (mat_complex_split_t *)data; - ci = (mat_complex_split_t *)matvar->internal->data; - err = GetDataLinear(ci->Re, co->Re, matvar->class_type, matvar->data_type, start, - stride, edge); - if ( err == MATIO_E_NO_ERROR ) - err = GetDataLinear(ci->Im, co->Im, matvar->class_type, matvar->data_type, - start, stride, edge); - return err; - } else { - return GetDataLinear(matvar->internal->data, data, matvar->class_type, - matvar->data_type, start, stride, edge); - } - } - - matvar->internal->z->avail_in = 0; - err = inflateCopy(&z, matvar->internal->z); - if ( err != Z_OK ) { - Mat_Critical("inflateCopy returned error %s", zError(err)); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - err = Inflate(mat, &z, tag, 4, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - (void)Mat_int32Swap(tag + 1); - } - matvar->data_type = (enum matio_types)(tag[0] & 0x000000ff); - if ( !(tag[0] & 0xffff0000) ) { /* Data is NOT packed in the tag */ - err = Inflate(mat, &z, tag + 1, 4, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag + 1); - } - real_bytes = 8 + tag[1]; - } else { - real_bytes = 4 + (tag[0] >> 16); - } -#endif - } - if ( real_bytes % 8 ) - real_bytes += (8 - (real_bytes % 8)); - - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - if ( (size_t)stride * (edge - 1) + start + 1 > nelems ) { - err = MATIO_E_BAD_ARGUMENT; - } else if ( matvar->compression == MAT_COMPRESSION_NONE ) { - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)data; - - ReadDataSlab1(mat, complex_data->Re, matvar->class_type, matvar->data_type, start, - stride, edge); - (void)fseek((FILE *)mat->fp, matvar->internal->datapos + real_bytes, SEEK_SET); - err = Read(tag, 4, 2, (FILE *)mat->fp, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - (void)Mat_int32Swap(tag + 1); - } - matvar->data_type = (enum matio_types)(tag[0] & 0x000000ff); - if ( tag[0] & 0xffff0000 ) { /* Data is packed in the tag */ - (void)fseek((FILE *)mat->fp, -4, SEEK_CUR); - } - ReadDataSlab1(mat, complex_data->Im, matvar->class_type, matvar->data_type, start, - stride, edge); - } else { - ReadDataSlab1(mat, data, matvar->class_type, matvar->data_type, start, stride, edge); - } -#if HAVE_ZLIB - } else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - if ( matvar->isComplex ) { - mat_complex_split_t *complex_data = (mat_complex_split_t *)data; - - ReadCompressedDataSlab1(mat, &z, complex_data->Re, matvar->class_type, - matvar->data_type, start, stride, edge); - - (void)fseek((FILE *)mat->fp, matvar->internal->datapos, SEEK_SET); - - /* Reset zlib knowledge to before reading real tag */ - inflateEnd(&z); - err = inflateCopy(&z, matvar->internal->z); - if ( err != Z_OK ) { - Mat_Critical("inflateCopy returned error %s", zError(err)); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - InflateSkip(mat, &z, real_bytes, NULL); - z.avail_in = 0; - err = Inflate(mat, &z, tag, 4, NULL); - if ( err ) { - return err; - } - if ( mat->byteswap ) { - (void)Mat_int32Swap(tag); - } - matvar->data_type = (enum matio_types)(tag[0] & 0x000000ff); - if ( !(tag[0] & 0xffff0000) ) { /*Data is NOT packed in the tag*/ - InflateSkip(mat, &z, 4, NULL); - } - ReadCompressedDataSlab1(mat, &z, complex_data->Im, matvar->class_type, - matvar->data_type, start, stride, edge); - } else { - ReadCompressedDataSlab1(mat, &z, data, matvar->class_type, matvar->data_type, start, - stride, edge); - } - inflateEnd(&z); -#endif - } - - matvar->data_type = ClassType2DataType(matvar->class_type); - matvar->data_size = Mat_SizeOfClass(matvar->class_type); - - return err; -} - -/** @if mat_devman - * @brief Writes a matlab variable to a version 5 matlab file - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @param compress option to compress the variable - * (only works for numeric types) - * @retval 0 on success - * @endif - */ -static int -Mat_VarWrite5(mat_t *mat, matvar_t *matvar, int compress) -{ - mat_uint32_t array_flags; - int array_flags_type = MAT_T_UINT32, dims_array_type = MAT_T_INT32; - int array_flags_size = 8, matrix_type = MAT_T_MATRIX; - const mat_uint32_t pad4 = 0; - int nBytes, i, nzmax = 0; - long start = 0, end = 0; - - if ( NULL == mat ) - return MATIO_E_BAD_ARGUMENT; - - /* FIXME: SEEK_END is not Guaranteed by the C standard */ - (void)fseek((FILE *)mat->fp, 0, SEEK_END); /* Always write at end of file */ - - if ( NULL == matvar || NULL == matvar->name ) - return MATIO_E_BAD_ARGUMENT; - -#if HAVE_ZLIB - if ( compress == MAT_COMPRESSION_NONE ) { -#else - { -#endif - fwrite(&matrix_type, 4, 1, (FILE *)mat->fp); - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - start = ftell((FILE *)mat->fp); - - /* Array Flags */ - array_flags = matvar->class_type & CLASS_TYPE_MASK; - if ( matvar->isComplex ) - array_flags |= MAT_F_COMPLEX; - if ( matvar->isGlobal ) - array_flags |= MAT_F_GLOBAL; - if ( matvar->isLogical ) - array_flags |= MAT_F_LOGICAL; - if ( matvar->class_type == MAT_C_SPARSE ) - nzmax = ((mat_sparse_t *)matvar->data)->nzmax; - - fwrite(&array_flags_type, 4, 1, (FILE *)mat->fp); - fwrite(&array_flags_size, 4, 1, (FILE *)mat->fp); - fwrite(&array_flags, 4, 1, (FILE *)mat->fp); - fwrite(&nzmax, 4, 1, (FILE *)mat->fp); - /* Rank and Dimension */ - nBytes = matvar->rank * 4; - fwrite(&dims_array_type, 4, 1, (FILE *)mat->fp); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - for ( i = 0; i < matvar->rank; i++ ) { - mat_int32_t dim; - dim = matvar->dims[i]; - fwrite(&dim, 4, 1, (FILE *)mat->fp); - } - if ( matvar->rank % 2 != 0 ) - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - /* Name of variable */ - if ( strlen(matvar->name) <= 4 ) { - mat_uint32_t array_name_type = MAT_T_INT8; - const mat_uint32_t array_name_len = (mat_uint32_t)strlen(matvar->name); - const mat_uint8_t pad1 = 0; - array_name_type |= array_name_len << 16; - fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - fwrite(matvar->name, 1, array_name_len, (FILE *)mat->fp); - for ( i = array_name_len; i < 4; i++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } else { - const mat_uint32_t array_name_type = MAT_T_INT8; - const mat_uint32_t array_name_len = (mat_uint32_t)strlen(matvar->name); - const mat_uint8_t pad1 = 0; - - fwrite(&array_name_type, 4, 1, (FILE *)mat->fp); - fwrite(&array_name_len, 4, 1, (FILE *)mat->fp); - fwrite(matvar->name, 1, array_name_len, (FILE *)mat->fp); - if ( array_name_len % 8 ) - for ( i = array_name_len % 8; i < 8; i++ ) - fwrite(&pad1, 1, 1, (FILE *)mat->fp); - } - - if ( NULL != matvar->internal ) { - matvar->internal->datapos = ftell((FILE *)mat->fp); - if ( matvar->internal->datapos == -1L ) { - Mat_Critical("Couldn't determine file position"); - return MATIO_E_GENERIC_READ_ERROR; - } - } else { - /* Must be empty */ - matvar->class_type = MAT_C_EMPTY; - } - WriteType(mat, matvar); -#if HAVE_ZLIB - } else if ( compress == MAT_COMPRESSION_ZLIB ) { - mat_uint32_t comp_buf[512]; - mat_uint32_t uncomp_buf[512]; - int buf_size = 512, err; - size_t byteswritten = 0, matrix_max_buf_size; - z_streamp z; - - z = (z_streamp)calloc(1, sizeof(*z)); - if ( z == NULL ) - return MATIO_E_OUT_OF_MEMORY; - err = deflateInit(z, Z_DEFAULT_COMPRESSION); - if ( err != Z_OK ) { - free(z); - Mat_Critical("deflateInit returned %s", zError(err)); - return MATIO_E_FILE_FORMAT_VIOLATION; - } - - matrix_type = MAT_T_COMPRESSED; - fwrite(&matrix_type, 4, 1, (FILE *)mat->fp); - fwrite(&pad4, 4, 1, (FILE *)mat->fp); - start = ftell((FILE *)mat->fp); - - /* Array Flags */ - array_flags = matvar->class_type & CLASS_TYPE_MASK; - if ( matvar->isComplex ) - array_flags |= MAT_F_COMPLEX; - if ( matvar->isGlobal ) - array_flags |= MAT_F_GLOBAL; - if ( matvar->isLogical ) - array_flags |= MAT_F_LOGICAL; - if ( matvar->class_type == MAT_C_SPARSE ) - nzmax = ((mat_sparse_t *)matvar->data)->nzmax; - - memset(&uncomp_buf, 0, sizeof(uncomp_buf)); - uncomp_buf[0] = MAT_T_MATRIX; - err = GetMatrixMaxBufSize(matvar, &matrix_max_buf_size); - if ( err ) { - free(z); - return err; - } - if ( matrix_max_buf_size > UINT32_MAX ) { - free(z); - return MATIO_E_INDEX_TOO_BIG; - } - uncomp_buf[1] = matrix_max_buf_size; - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += - fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - uncomp_buf[0] = array_flags_type; - uncomp_buf[1] = array_flags_size; - uncomp_buf[2] = array_flags; - uncomp_buf[3] = nzmax; - /* Rank and Dimension */ - nBytes = matvar->rank * 4; - uncomp_buf[4] = dims_array_type; - uncomp_buf[5] = nBytes; - for ( i = 0; i < matvar->rank; i++ ) { - mat_int32_t dim; - dim = matvar->dims[i]; - uncomp_buf[6 + i] = dim; - } - if ( matvar->rank % 2 != 0 ) { - uncomp_buf[6 + i] = pad4; - i++; - } - - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = (6 + i) * sizeof(*uncomp_buf); - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += - fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - /* Name of variable */ - if ( strlen(matvar->name) <= 4 ) { - mat_uint32_t array_name_len = (mat_uint32_t)strlen(matvar->name); - const mat_uint32_t array_name_type = MAT_T_INT8; - - memset(uncomp_buf, 0, 8); - uncomp_buf[0] = (array_name_len << 16) | array_name_type; - memcpy(uncomp_buf + 1, matvar->name, array_name_len); - if ( array_name_len % 4 ) - array_name_len += 4 - (array_name_len % 4); - - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, - (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - } else { - mat_uint32_t array_name_len = (mat_uint32_t)strlen(matvar->name); - const mat_uint32_t array_name_type = MAT_T_INT8; - - memset(uncomp_buf, 0, buf_size * sizeof(*uncomp_buf)); - uncomp_buf[0] = array_name_type; - uncomp_buf[1] = array_name_len; - memcpy(uncomp_buf + 2, matvar->name, array_name_len); - if ( array_name_len % 8 ) - array_name_len += 8 - (array_name_len % 8); - z->next_in = ZLIB_BYTE_PTR(uncomp_buf); - z->avail_in = 8 + array_name_len; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - deflate(z, Z_NO_FLUSH); - byteswritten += fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, - (FILE *)mat->fp); - } while ( z->avail_out == 0 ); - } - if ( NULL != matvar->internal ) { - matvar->internal->datapos = ftell((FILE *)mat->fp); - if ( matvar->internal->datapos == -1L ) { - free(z); - Mat_Critical("Couldn't determine file position"); - return MATIO_E_GENERIC_READ_ERROR; - } - } else { - /* Must be empty */ - matvar->class_type = MAT_C_EMPTY; - } - WriteCompressedType(mat, matvar, z); - z->next_in = NULL; - z->avail_in = 0; - do { - z->next_out = ZLIB_BYTE_PTR(comp_buf); - z->avail_out = buf_size * sizeof(*comp_buf); - err = deflate(z, Z_FINISH); - byteswritten += - fwrite(comp_buf, 1, buf_size * sizeof(*comp_buf) - z->avail_out, (FILE *)mat->fp); - } while ( err != Z_STREAM_END && z->avail_out == 0 ); - (void)deflateEnd(z); - free(z); -#endif - } - end = ftell((FILE *)mat->fp); - if ( start != -1L && end != -1L ) { - nBytes = (int)(end - start); - (void)fseek((FILE *)mat->fp, (long)-(nBytes + 4), SEEK_CUR); - fwrite(&nBytes, 4, 1, (FILE *)mat->fp); - (void)fseek((FILE *)mat->fp, end, SEEK_SET); - } else { - Mat_Critical("Couldn't determine file position"); - } - - return MATIO_E_NO_ERROR; -} - -/** @if mat_devman - * @brief Reads the header information for the next MAT variable - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @return pointer to the MAT variable or NULL - * @endif - */ -static matvar_t * -Mat_VarReadNextInfo5(mat_t *mat) -{ - int err; - mat_uint32_t data_type, array_flags, nBytes; - long fpos; - matvar_t *matvar = NULL; - - if ( mat == NULL || mat->fp == NULL ) - return NULL; - - if ( IsEndOfFile((FILE *)mat->fp, &fpos) ) - return NULL; - - if ( fpos == -1L ) - return NULL; - - { - size_t nbytes = 0; - err = Read(&data_type, sizeof(mat_uint32_t), 1, (FILE *)mat->fp, &nbytes); - if ( err || 0 == nbytes ) - return NULL; - } - err = Read(&nBytes, sizeof(mat_uint32_t), 1, (FILE *)mat->fp, NULL); - if ( err ) - return NULL; - if ( mat->byteswap ) { - (void)Mat_uint32Swap(&data_type); - (void)Mat_uint32Swap(&nBytes); - } - if ( nBytes > INT32_MAX - 8 - (mat_uint32_t)fpos ) - return NULL; - switch ( data_type ) { - case MAT_T_COMPRESSED: { -#if HAVE_ZLIB - mat_uint32_t uncomp_buf[16]; - int nbytes; - size_t bytesread = 0; - - memset(&uncomp_buf, 0, sizeof(uncomp_buf)); - matvar = Mat_VarCalloc(); - if ( NULL == matvar ) { - Mat_Critical("Couldn't allocate memory"); - break; - } - - matvar->compression = MAT_COMPRESSION_ZLIB; - matvar->internal->z = (z_streamp)calloc(1, sizeof(z_stream)); - err = inflateInit(matvar->internal->z); - if ( err != Z_OK ) { - Mat_VarFree(matvar); - matvar = NULL; - Mat_Critical("inflateInit returned %s", zError(err)); - break; - } - - /* Read variable tag */ - err = Inflate(mat, matvar->internal->z, uncomp_buf, 8, &bytesread); - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - } - nbytes = uncomp_buf[1]; - if ( uncomp_buf[0] != MAT_T_MATRIX ) { - (void)fseek((FILE *)mat->fp, (long)(nBytes - bytesread), SEEK_CUR); - Mat_VarFree(matvar); - matvar = NULL; - Mat_Critical("Uncompressed type not MAT_T_MATRIX"); - break; - } - /* Array flags */ - err = Inflate(mat, matvar->internal->z, uncomp_buf, 16, &bytesread); - if ( err ) { - Mat_VarFree(matvar); - matvar = NULL; - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 2); - (void)Mat_uint32Swap(uncomp_buf + 3); - } - /* Array flags */ - if ( uncomp_buf[0] == MAT_T_UINT32 ) { - array_flags = uncomp_buf[2]; - matvar->class_type = CLASS_FROM_ARRAY_FLAGS(array_flags); - matvar->isComplex = (array_flags & MAT_F_COMPLEX); - matvar->isGlobal = (array_flags & MAT_F_GLOBAL); - matvar->isLogical = (array_flags & MAT_F_LOGICAL); - if ( matvar->class_type == MAT_C_SPARSE ) { - /* Need to find a more appropriate place to store nzmax */ - matvar->nbytes = uncomp_buf[3]; - } - } - if ( matvar->class_type != MAT_C_OPAQUE ) { - mat_uint32_t *dims = NULL; - int do_clean = 0; - err = InflateRankDims(mat, matvar->internal->z, uncomp_buf, sizeof(uncomp_buf), - &dims, &bytesread); - if ( NULL == dims ) { - dims = uncomp_buf + 2; - } else { - do_clean = 1; - } - if ( err ) { - if ( do_clean ) { - free(dims); - } - Mat_VarFree(matvar); - matvar = NULL; - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(uncomp_buf); - (void)Mat_uint32Swap(uncomp_buf + 1); - } - /* Rank and dimension */ - if ( uncomp_buf[0] == MAT_T_INT32 ) { - int j; - size_t size; - nbytes = uncomp_buf[1]; - matvar->rank = nbytes / 4; - if ( 0 == do_clean && matvar->rank > 13 ) { - int rank = matvar->rank; - matvar->rank = 0; - Mat_Critical("%d is not a valid rank", rank); - break; - } - err = Mul(&size, matvar->rank, sizeof(*matvar->dims)); - if ( err ) { - if ( do_clean ) { - free(dims); - } - (void)fseek((FILE *)mat->fp, (long)(nBytes - bytesread), SEEK_CUR); - Mat_VarFree(matvar); - matvar = NULL; - Mat_Critical("Integer multiplication overflow"); - break; - } - matvar->dims = (size_t *)malloc(size); - if ( NULL == matvar->dims ) { - if ( do_clean ) - free(dims); - (void)fseek((FILE *)mat->fp, (long)(nBytes - bytesread), SEEK_CUR); - Mat_VarFree(matvar); - matvar = NULL; - Mat_Critical("Couldn't allocate memory"); - break; - } - if ( mat->byteswap ) { - for ( j = 0; j < matvar->rank; j++ ) - matvar->dims[j] = Mat_uint32Swap(dims + j); - } else { - for ( j = 0; j < matvar->rank; j++ ) - matvar->dims[j] = dims[j]; - } - } - if ( do_clean ) { - free(dims); - } - /* Variable name tag */ - err = Inflate(mat, matvar->internal->z, uncomp_buf, 8, &bytesread); - if ( err ) { - Mat_VarFree(matvar); - matvar = NULL; - break; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(uncomp_buf); - /* Name of variable */ - if ( uncomp_buf[0] == MAT_T_INT8 ) { /* Name not in tag */ - mat_uint32_t len, len_pad; - if ( mat->byteswap ) - len = Mat_uint32Swap(uncomp_buf + 1); - else - len = uncomp_buf[1]; - - if ( len % 8 == 0 ) - len_pad = len; - else if ( len < UINT32_MAX - 8 + (len % 8) ) - len_pad = len + 8 - (len % 8); - else { - Mat_VarFree(matvar); - matvar = NULL; - break; - } - matvar->name = (char *)malloc(len_pad + 1); - if ( NULL != matvar->name ) { - /* Variable name */ - err = Inflate(mat, matvar->internal->z, matvar->name, len_pad, &bytesread); - if ( err ) { - Mat_VarFree(matvar); - matvar = NULL; - break; - } - matvar->name[len] = '\0'; - } - } else { - mat_uint32_t len = (uncomp_buf[0] & 0xffff0000) >> 16; - if ( ((uncomp_buf[0] & 0x0000ffff) == MAT_T_INT8) && len > 0 && len <= 4 ) { - /* Name packed in tag */ - matvar->name = (char *)malloc(len + 1); - if ( NULL != matvar->name ) { - memcpy(matvar->name, uncomp_buf + 1, len); - matvar->name[len] = '\0'; - } - } - } - if ( matvar->class_type == MAT_C_STRUCT ) - (void)ReadNextStructField(mat, matvar); - else if ( matvar->class_type == MAT_C_CELL ) - (void)ReadNextCell(mat, matvar); - (void)fseek((FILE *)mat->fp, -(int)matvar->internal->z->avail_in, SEEK_CUR); - matvar->internal->datapos = ftell((FILE *)mat->fp); - if ( matvar->internal->datapos == -1L ) { - Mat_Critical("Couldn't determine file position"); - } - } - (void)fseek((FILE *)mat->fp, nBytes + 8 + fpos, SEEK_SET); - break; -#else - Mat_Critical( - "Compressed variable found in \"%s\", but matio was " - "built without zlib support", - mat->filename); - (void)fseek((FILE *)mat->fp, nBytes + 8 + fpos, SEEK_SET); - return NULL; -#endif - } - case MAT_T_MATRIX: { - mat_uint32_t buf[6]; - - /* Read array flags and the dimensions tag */ - err = Read(buf, 4, 6, (FILE *)mat->fp, NULL); - if ( err ) { - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - break; - } - if ( mat->byteswap ) { - (void)Mat_uint32Swap(buf); - (void)Mat_uint32Swap(buf + 1); - (void)Mat_uint32Swap(buf + 2); - (void)Mat_uint32Swap(buf + 3); - (void)Mat_uint32Swap(buf + 4); - (void)Mat_uint32Swap(buf + 5); - } - - matvar = Mat_VarCalloc(); - if ( NULL == matvar ) { - Mat_Critical("Couldn't allocate memory"); - break; - } - - /* Array flags */ - if ( buf[0] == MAT_T_UINT32 || buf[0] == MAT_T_INT32 ) { /* Also allow INT32 for SWAN */ - array_flags = buf[2]; - matvar->class_type = CLASS_FROM_ARRAY_FLAGS(array_flags); - matvar->isComplex = (array_flags & MAT_F_COMPLEX); - matvar->isGlobal = (array_flags & MAT_F_GLOBAL); - matvar->isLogical = (array_flags & MAT_F_LOGICAL); - if ( matvar->class_type == MAT_C_SPARSE ) { - /* Need to find a more appropriate place to store nzmax */ - matvar->nbytes = buf[3]; - } - } - /* Rank and dimension */ - { - size_t nbytes = 0; - err = ReadRankDims(mat, matvar, (enum matio_types)buf[4], buf[5], &nbytes); - if ( err ) { - Mat_VarFree(matvar); - matvar = NULL; - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - break; - } - } - /* Variable name tag */ - err = Read(buf, 4, 2, (FILE *)mat->fp, NULL); - if ( err ) { - Mat_VarFree(matvar); - matvar = NULL; - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - break; - } - if ( mat->byteswap ) - (void)Mat_uint32Swap(buf); - /* Name of variable */ - if ( buf[0] == MAT_T_INT8 ) { /* Name not in tag */ - mat_uint32_t len, len_pad; - if ( mat->byteswap ) - len = Mat_uint32Swap(buf + 1); - else - len = buf[1]; - if ( len % 8 == 0 ) - len_pad = len; - else if ( len < UINT32_MAX - 8 + (len % 8) ) - len_pad = len + 8 - (len % 8); - else { - Mat_VarFree(matvar); - matvar = NULL; - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - break; - } - matvar->name = (char *)malloc(len_pad + 1); - if ( NULL != matvar->name ) { - err = Read(matvar->name, 1, len_pad, (FILE *)mat->fp, NULL); - if ( MATIO_E_NO_ERROR == err ) { - matvar->name[len] = '\0'; - } else { - Mat_VarFree(matvar); - matvar = NULL; - (void)fseek((FILE *)mat->fp, fpos, SEEK_SET); - break; - } - } - } else { - mat_uint32_t len = (buf[0] & 0xffff0000) >> 16; - if ( ((buf[0] & 0x0000ffff) == MAT_T_INT8) && len > 0 && len <= 4 ) { - /* Name packed in tag */ - matvar->name = (char *)malloc(len + 1); - if ( NULL != matvar->name ) { - memcpy(matvar->name, buf + 1, len); - matvar->name[len] = '\0'; - } - } - } - if ( matvar->class_type == MAT_C_STRUCT ) - (void)ReadNextStructField(mat, matvar); - else if ( matvar->class_type == MAT_C_CELL ) - (void)ReadNextCell(mat, matvar); - else if ( matvar->class_type == MAT_C_FUNCTION ) - (void)ReadNextFunctionHandle(mat, matvar); - matvar->internal->datapos = ftell((FILE *)mat->fp); - if ( matvar->internal->datapos == -1L ) { - Mat_Critical("Couldn't determine file position"); - } - (void)fseek((FILE *)mat->fp, nBytes + 8 + fpos, SEEK_SET); - break; - } - default: - Mat_Critical("%d is not valid (MAT_T_MATRIX or MAT_T_COMPRESSED)", data_type); - return NULL; - } - - return matvar; -} - -/* ------------------------------- - * ---------- mat73.c - * ------------------------------- - */ -/** @file mat73.c - * Matlab MAT version 7.3 file functions - * @ingroup MAT - */ - -#if HAVE_HDF5 - -static const char *ClassNames[] = {"", "cell", "struct", "object", "char", "sparse", - "double", "single", "int8", "uint8", "int16", "uint16", - "int32", "uint32", "int64", "uint64", "function"}; - -struct ReadNextIterData -{ - mat_t *mat; - matvar_t *matvar; -}; - -struct ReadGroupInfoIterData -{ - hsize_t nfields; - matvar_t *matvar; -}; - -#if H5_VERSION_GE(1, 10, 0) -#define H5RDEREFERENCE(obj_id, ref_type, _ref) \ - H5Rdereference2((obj_id), H5P_DATASET_ACCESS_DEFAULT, (ref_type), (_ref)) -#else -#define H5RDEREFERENCE(obj_id, ref_type, _ref) H5Rdereference((obj_id), (ref_type), (_ref)) -#endif - -#if H5_VERSION_GE(1, 12, 0) -#define H5O_INFO_T H5O_info2_t -#define H5OGET_INFO_BY_NAME(loc_id, name, oinfo, lapl_id) \ - H5Oget_info_by_name3((loc_id), (name), (oinfo), H5O_INFO_BASIC, (lapl_id)); -#elif H5_VERSION_GE(1, 10, 3) -#define H5O_INFO_T H5O_info_t -#define H5OGET_INFO_BY_NAME(loc_id, name, oinfo, lapl_id) \ - H5Oget_info_by_name2((loc_id), (name), (oinfo), H5O_INFO_BASIC, (lapl_id)); -#else -#define H5O_INFO_T H5O_info_t -#define H5OGET_INFO_BY_NAME(loc_id, name, oinfo, lapl_id) \ - H5Oget_info_by_name((loc_id), (name), (oinfo), (lapl_id)); -#endif - -#if !defined(MAX_RANK) -/* Maximal number of dimensions for stack allocated temporary dimension arrays */ -#define MAX_RANK (3) -#endif - -/*=========================================================================== - * Private functions - *=========================================================================== - */ -static enum matio_classes ClassStr2ClassType(const char *name); -static enum matio_classes DataType2ClassType(enum matio_types type); -static hid_t ClassType2H5T(enum matio_classes class_type); -static hid_t DataType2H5T(enum matio_types data_type); -static hid_t SizeType2H5T(void); -static hid_t DataType(hid_t h5_type, int isComplex); -static void Mat_H5GetChunkSize(size_t rank, hsize_t *dims, hsize_t *chunk_dims); -static int Mat_H5ReadVarInfo(matvar_t *matvar, hid_t dset_id); -static size_t *Mat_H5ReadDims(hid_t dset_id, hsize_t *nelems, int *rank); -static int Mat_H5ReadFieldNames(matvar_t *matvar, hid_t dset_id, hsize_t *nfields); -static int Mat_H5ReadDatasetInfo(mat_t *mat, matvar_t *matvar, hid_t dset_id); -static int Mat_H5ReadGroupInfo(mat_t *mat, matvar_t *matvar, hid_t dset_id); -static int Mat_H5ReadNextReferenceInfo(hid_t ref_id, matvar_t *matvar, mat_t *mat); -static int Mat_H5ReadNextReferenceData(hid_t ref_id, matvar_t *matvar, mat_t *mat); -static int Mat_VarWriteEmpty(hid_t id, matvar_t *matvar, const char *name, const char *class_name); -static int Mat_VarWriteCell73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, - hsize_t *dims); -static int Mat_VarWriteChar73(hid_t id, matvar_t *matvar, const char *name, hsize_t *dims); -static int Mat_WriteEmptyVariable73(hid_t id, const char *name, hsize_t rank, size_t *dims); -static int Mat_VarWriteLogical73(hid_t id, matvar_t *matvar, const char *name, hsize_t *dims); -static int Mat_VarWriteNumeric73(hid_t id, matvar_t *matvar, const char *name, hsize_t *dims, - hsize_t *max_dims); -static int Mat_VarWriteAppendNumeric73(hid_t id, matvar_t *matvar, const char *name, hsize_t *dims, - int dim); -static int Mat_VarWriteSparse73(hid_t id, matvar_t *matvar, const char *name); -static int Mat_VarWriteStruct73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, - hsize_t *dims, hsize_t *max_dims); -static int Mat_VarWriteAppendStruct73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, - hsize_t *dims, int dim); -static int Mat_VarWriteNext73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id); -static int Mat_VarWriteAppendNext73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, - int dim); -static int Mat_VarWriteNextType73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, - hsize_t *dims); -static int Mat_VarWriteAppendNextType73(hid_t id, matvar_t *matvar, const char *name, - hid_t *refs_id, hsize_t *dims, int dim); -static herr_t Mat_VarReadNextInfoIterate(hid_t id, const char *name, const H5L_info_t *info, - void *op_data); -static herr_t Mat_H5ReadGroupInfoIterate(hid_t dset_id, const char *name, const H5L_info_t *info, - void *op_data); -static int Mat_H5ReadData(hid_t dset_id, hid_t h5_type, hid_t mem_space, hid_t dset_space, - int isComplex, void *data); -static int Mat_H5WriteData(hid_t dset_id, hid_t h5_type, hid_t mem_space, hid_t dset_space, - int isComplex, void *data); -static int Mat_H5WriteAppendData(hid_t id, hid_t h5_type, int mrank, const char *name, - const size_t *mdims, hsize_t *dims, int dim, int isComplex, - void *data); -static int Mat_VarWriteRef(hid_t id, matvar_t *matvar, enum matio_compression compression, - hid_t *refs_id, hobj_ref_t *ref); - -static enum matio_classes -ClassStr2ClassType(const char *name) -{ - enum matio_classes id = MAT_C_EMPTY; - if ( NULL != name ) { - int k; - for ( k = 1; k < 17; k++ ) { - if ( 0 == strcmp(name, ClassNames[k]) ) { - id = (enum matio_classes)k; - break; - } - } - } - - return id; -} - -static enum matio_classes -DataType2ClassType(enum matio_types type) -{ - switch ( type ) { - case MAT_T_DOUBLE: - return MAT_C_DOUBLE; - case MAT_T_SINGLE: - return MAT_C_SINGLE; -#ifdef HAVE_MATIO_INT64_T - case MAT_T_INT64: - return MAT_C_INT64; -#endif -#ifdef HAVE_MATIO_UINT64_T - case MAT_T_UINT64: - return MAT_C_UINT64; -#endif - case MAT_T_INT32: - return MAT_C_INT32; - case MAT_T_UINT32: - return MAT_C_UINT32; - case MAT_T_INT16: - return MAT_C_INT16; - case MAT_T_UINT16: - return MAT_C_UINT16; - case MAT_T_INT8: - return MAT_C_INT8; - case MAT_T_UINT8: - return MAT_C_UINT8; - default: - return MAT_C_EMPTY; - } -} - -static hid_t -ClassType2H5T(enum matio_classes class_type) -{ - switch ( class_type ) { - case MAT_C_DOUBLE: - return H5T_NATIVE_DOUBLE; - case MAT_C_SINGLE: - return H5T_NATIVE_FLOAT; - case MAT_C_INT64: - if ( CHAR_BIT * sizeof(long long) == 64 ) - return H5T_NATIVE_LLONG; - else if ( CHAR_BIT * sizeof(long) == 64 ) - return H5T_NATIVE_LONG; - else if ( CHAR_BIT * sizeof(int) == 64 ) - return H5T_NATIVE_INT; - else if ( CHAR_BIT * sizeof(short) == 64 ) - return H5T_NATIVE_SHORT; - else - return -1; - case MAT_C_UINT64: - if ( CHAR_BIT * sizeof(long long) == 64 ) - return H5T_NATIVE_ULLONG; - else if ( CHAR_BIT * sizeof(long) == 64 ) - return H5T_NATIVE_ULONG; - else if ( CHAR_BIT * sizeof(int) == 64 ) - return H5T_NATIVE_UINT; - if ( CHAR_BIT * sizeof(short) == 64 ) - return H5T_NATIVE_USHORT; - else - return -1; - case MAT_C_INT32: - if ( CHAR_BIT * sizeof(int) == 32 ) - return H5T_NATIVE_INT; - else if ( CHAR_BIT * sizeof(short) == 32 ) - return H5T_NATIVE_SHORT; - else if ( CHAR_BIT * sizeof(long) == 32 ) - return H5T_NATIVE_LONG; - else if ( CHAR_BIT * sizeof(long long) == 32 ) - return H5T_NATIVE_LLONG; - else if ( CHAR_BIT == 32 ) - return H5T_NATIVE_SCHAR; - else - return -1; - case MAT_C_UINT32: - if ( CHAR_BIT * sizeof(int) == 32 ) - return H5T_NATIVE_UINT; - else if ( CHAR_BIT * sizeof(short) == 32 ) - return H5T_NATIVE_USHORT; - else if ( CHAR_BIT * sizeof(long) == 32 ) - return H5T_NATIVE_ULONG; - else if ( CHAR_BIT * sizeof(long long) == 32 ) - return H5T_NATIVE_ULLONG; - else if ( CHAR_BIT == 32 ) - return H5T_NATIVE_UCHAR; - else - return -1; - case MAT_C_INT16: - if ( CHAR_BIT * sizeof(short) == 16 ) - return H5T_NATIVE_SHORT; - else if ( CHAR_BIT * sizeof(int) == 16 ) - return H5T_NATIVE_INT; - else if ( CHAR_BIT * sizeof(long) == 16 ) - return H5T_NATIVE_LONG; - else if ( CHAR_BIT * sizeof(long long) == 16 ) - return H5T_NATIVE_LLONG; - else if ( CHAR_BIT == 16 ) - return H5T_NATIVE_SCHAR; - else - return -1; - case MAT_C_UINT16: - if ( CHAR_BIT * sizeof(short) == 16 ) - return H5T_NATIVE_USHORT; - else if ( CHAR_BIT * sizeof(int) == 16 ) - return H5T_NATIVE_UINT; - else if ( CHAR_BIT * sizeof(long) == 16 ) - return H5T_NATIVE_ULONG; - else if ( CHAR_BIT * sizeof(long long) == 16 ) - return H5T_NATIVE_ULLONG; - else if ( CHAR_BIT == 16 ) - return H5T_NATIVE_UCHAR; - else - return -1; - case MAT_C_INT8: - if ( CHAR_BIT == 8 ) - return H5T_NATIVE_SCHAR; - else if ( CHAR_BIT * sizeof(short) == 8 ) - return H5T_NATIVE_SHORT; - else if ( CHAR_BIT * sizeof(int) == 8 ) - return H5T_NATIVE_INT; - else if ( CHAR_BIT * sizeof(long) == 8 ) - return H5T_NATIVE_LONG; - else if ( CHAR_BIT * sizeof(long long) == 8 ) - return H5T_NATIVE_LLONG; - else - return -1; - case MAT_C_UINT8: - if ( CHAR_BIT == 8 ) - return H5T_NATIVE_UCHAR; - else if ( CHAR_BIT * sizeof(short) == 8 ) - return H5T_NATIVE_USHORT; - else if ( CHAR_BIT * sizeof(int) == 8 ) - return H5T_NATIVE_UINT; - else if ( CHAR_BIT * sizeof(long) == 8 ) - return H5T_NATIVE_ULONG; - else if ( CHAR_BIT * sizeof(long long) == 8 ) - return H5T_NATIVE_ULLONG; - else - return -1; - default: - return -1; - } -} - -static hid_t -DataType2H5T(enum matio_types data_type) -{ - switch ( data_type ) { - case MAT_T_DOUBLE: - return H5T_NATIVE_DOUBLE; - case MAT_T_SINGLE: - return H5T_NATIVE_FLOAT; - case MAT_T_INT64: - if ( CHAR_BIT * sizeof(long long) == 64 ) - return H5T_NATIVE_LLONG; - else if ( CHAR_BIT * sizeof(long) == 64 ) - return H5T_NATIVE_LONG; - else if ( CHAR_BIT * sizeof(int) == 64 ) - return H5T_NATIVE_INT; - else if ( CHAR_BIT * sizeof(short) == 64 ) - return H5T_NATIVE_SHORT; - else - return -1; - case MAT_T_UINT64: - if ( CHAR_BIT * sizeof(long long) == 64 ) - return H5T_NATIVE_ULLONG; - else if ( CHAR_BIT * sizeof(long) == 64 ) - return H5T_NATIVE_ULONG; - else if ( CHAR_BIT * sizeof(int) == 64 ) - return H5T_NATIVE_UINT; - else if ( CHAR_BIT * sizeof(short) == 64 ) - return H5T_NATIVE_USHORT; - else - return -1; - case MAT_T_INT32: - if ( CHAR_BIT * sizeof(int) == 32 ) - return H5T_NATIVE_INT; - else if ( CHAR_BIT * sizeof(short) == 32 ) - return H5T_NATIVE_SHORT; - else if ( CHAR_BIT * sizeof(long) == 32 ) - return H5T_NATIVE_LONG; - else if ( CHAR_BIT * sizeof(long long) == 32 ) - return H5T_NATIVE_LLONG; - else if ( CHAR_BIT == 32 ) - return H5T_NATIVE_SCHAR; - else - return -1; - case MAT_T_UINT32: - if ( CHAR_BIT * sizeof(int) == 32 ) - return H5T_NATIVE_UINT; - else if ( CHAR_BIT * sizeof(short) == 32 ) - return H5T_NATIVE_USHORT; - else if ( CHAR_BIT * sizeof(long) == 32 ) - return H5T_NATIVE_ULONG; - else if ( CHAR_BIT * sizeof(long long) == 32 ) - return H5T_NATIVE_ULLONG; - else if ( CHAR_BIT == 32 ) - return H5T_NATIVE_UCHAR; - else - return -1; - case MAT_T_INT16: - if ( CHAR_BIT * sizeof(short) == 16 ) - return H5T_NATIVE_SHORT; - else if ( CHAR_BIT * sizeof(int) == 16 ) - return H5T_NATIVE_INT; - else if ( CHAR_BIT * sizeof(long) == 16 ) - return H5T_NATIVE_LONG; - else if ( CHAR_BIT * sizeof(long long) == 16 ) - return H5T_NATIVE_LLONG; - else if ( CHAR_BIT == 16 ) - return H5T_NATIVE_SCHAR; - else - return -1; - case MAT_T_UINT16: - if ( CHAR_BIT * sizeof(short) == 16 ) - return H5T_NATIVE_USHORT; - else if ( CHAR_BIT * sizeof(int) == 16 ) - return H5T_NATIVE_UINT; - else if ( CHAR_BIT * sizeof(long) == 16 ) - return H5T_NATIVE_ULONG; - else if ( CHAR_BIT * sizeof(long long) == 16 ) - return H5T_NATIVE_ULLONG; - else if ( CHAR_BIT == 16 ) - return H5T_NATIVE_UCHAR; - else - return -1; - case MAT_T_INT8: - if ( CHAR_BIT == 8 ) - return H5T_NATIVE_SCHAR; - else if ( CHAR_BIT * sizeof(short) == 8 ) - return H5T_NATIVE_SHORT; - else if ( CHAR_BIT * sizeof(int) == 8 ) - return H5T_NATIVE_INT; - else if ( CHAR_BIT * sizeof(long) == 8 ) - return H5T_NATIVE_LONG; - else if ( CHAR_BIT * sizeof(long long) == 8 ) - return H5T_NATIVE_LLONG; - else - return -1; - case MAT_T_UINT8: - if ( CHAR_BIT == 8 ) - return H5T_NATIVE_UCHAR; - else if ( CHAR_BIT * sizeof(short) == 8 ) - return H5T_NATIVE_USHORT; - else if ( CHAR_BIT * sizeof(int) == 8 ) - return H5T_NATIVE_UINT; - else if ( CHAR_BIT * sizeof(long) == 8 ) - return H5T_NATIVE_ULONG; - else if ( CHAR_BIT * sizeof(long long) == 8 ) - return H5T_NATIVE_ULLONG; - else - return -1; - case MAT_T_UTF8: - return H5T_NATIVE_CHAR; - default: - return -1; - } -} - -static hid_t -SizeType2H5T(void) -{ - if ( sizeof(size_t) == H5Tget_size(H5T_NATIVE_HSIZE) ) - return H5T_NATIVE_HSIZE; - else if ( sizeof(size_t) == H5Tget_size(H5T_NATIVE_ULLONG) ) - return H5T_NATIVE_ULLONG; - else if ( sizeof(size_t) == H5Tget_size(H5T_NATIVE_ULONG) ) - return H5T_NATIVE_ULONG; - else if ( sizeof(size_t) == H5Tget_size(H5T_NATIVE_UINT) ) - return H5T_NATIVE_UINT; - else if ( sizeof(size_t) == H5Tget_size(H5T_NATIVE_USHORT) ) - return H5T_NATIVE_USHORT; - else - return -1; -} - -static hid_t -DataType(hid_t h5_type, int isComplex) -{ - hid_t h5_dtype; - if ( isComplex ) { - size_t h5_size = H5Tget_size(h5_type); - h5_dtype = H5Tcreate(H5T_COMPOUND, 2 * h5_size); - H5Tinsert(h5_dtype, "real", 0, h5_type); - H5Tinsert(h5_dtype, "imag", h5_size, h5_type); - } else { - h5_dtype = H5Tcopy(h5_type); - } - return h5_dtype; -} - -static void -Mat_H5GetChunkSize(size_t rank, hsize_t *dims, hsize_t *chunk_dims) -{ - hsize_t i, j, chunk_size = 1; - - for ( i = 0; i < rank; i++ ) { - chunk_dims[i] = 1; - for ( j = 4096 / chunk_size; j > 1; j >>= 1 ) { - if ( dims[i] >= j ) { - chunk_dims[i] = j; - break; - } - } - chunk_size *= chunk_dims[i]; - } -} - -static int -Mat_H5ReadVarInfo(matvar_t *matvar, hid_t dset_id) -{ - hid_t attr_id, type_id; - ssize_t name_len; - int err = MATIO_E_NO_ERROR; - - /* Get the HDF5 name of the variable */ - name_len = H5Iget_name(dset_id, NULL, 0); - if ( name_len > 0 ) { - matvar->internal->hdf5_name = (char *)malloc(name_len + 1); - (void)H5Iget_name(dset_id, matvar->internal->hdf5_name, name_len + 1); - } else { - /* Can not get an internal name, so leave the identifier open */ - matvar->internal->id = dset_id; - } - - attr_id = H5Aopen_by_name(dset_id, ".", "MATLAB_class", H5P_DEFAULT, H5P_DEFAULT); - type_id = H5Aget_type(attr_id); - if ( H5T_STRING == H5Tget_class(type_id) ) { - char *class_str = (char *)calloc(H5Tget_size(type_id) + 1, 1); - if ( NULL != class_str ) { - herr_t herr; - hid_t class_id = H5Tcopy(H5T_C_S1); - H5Tset_size(class_id, H5Tget_size(type_id)); - herr = H5Aread(attr_id, class_id, class_str); - H5Tclose(class_id); - if ( herr < 0 ) { - free(class_str); - H5Tclose(type_id); - H5Aclose(attr_id); - return MATIO_E_GENERIC_READ_ERROR; - } - matvar->class_type = ClassStr2ClassType(class_str); - if ( MAT_C_EMPTY == matvar->class_type || MAT_C_CHAR == matvar->class_type ) { - int int_decode = 0; - if ( H5Aexists_by_name(dset_id, ".", "MATLAB_int_decode", H5P_DEFAULT) ) { - hid_t attr_id2 = H5Aopen_by_name(dset_id, ".", "MATLAB_int_decode", H5P_DEFAULT, - H5P_DEFAULT); - /* FIXME: Check that dataspace is scalar */ - herr = H5Aread(attr_id2, H5T_NATIVE_INT, &int_decode); - H5Aclose(attr_id2); - if ( herr < 0 ) { - free(class_str); - H5Tclose(type_id); - H5Aclose(attr_id); - return MATIO_E_GENERIC_READ_ERROR; - } - } - switch ( int_decode ) { - case 2: - matvar->data_type = MAT_T_UINT16; - break; - case 1: - matvar->data_type = MAT_T_UINT8; - break; - case 4: - matvar->data_type = MAT_T_UINT32; - break; - default: - matvar->data_type = MAT_T_UNKNOWN; - break; - } - if ( MAT_C_EMPTY == matvar->class_type ) { - /* Check if this is a logical variable */ - if ( 0 == strcmp(class_str, "logical") ) { - matvar->isLogical = MAT_F_LOGICAL; - } - matvar->class_type = DataType2ClassType(matvar->data_type); - } else if ( MAT_T_UNKNOWN == matvar->data_type ) { - matvar->data_type = MAT_T_UINT16; - } - } else { - matvar->data_type = ClassType2DataType(matvar->class_type); - } - free(class_str); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - H5Tclose(type_id); - H5Aclose(attr_id); - - if ( err ) { - return err; - } - - /* Check if the variable is global */ - if ( H5Aexists_by_name(dset_id, ".", "MATLAB_global", H5P_DEFAULT) ) { - herr_t herr; - attr_id = H5Aopen_by_name(dset_id, ".", "MATLAB_global", H5P_DEFAULT, H5P_DEFAULT); - /* FIXME: Check that dataspace is scalar */ - herr = H5Aread(attr_id, H5T_NATIVE_INT, &matvar->isGlobal); - H5Aclose(attr_id); - if ( herr < 0 ) { - return MATIO_E_GENERIC_READ_ERROR; - } - } - - return err; -} - -static size_t * -Mat_H5ReadDims(hid_t dset_id, hsize_t *nelems, int *rank) -{ - hid_t space_id; - size_t *perm_dims; - - *nelems = 0; - space_id = H5Dget_space(dset_id); - *rank = H5Sget_simple_extent_ndims(space_id); - if ( 0 > *rank ) { - *rank = 0; - H5Sclose(space_id); - return NULL; - } - perm_dims = (size_t *)malloc(*rank * sizeof(*perm_dims)); - if ( NULL != perm_dims ) { - int err = 0; - if ( MAX_RANK >= *rank ) { - hsize_t dims[MAX_RANK]; - int k; - size_t tmp = 1; - (void)H5Sget_simple_extent_dims(space_id, dims, NULL); - /* Permute dimensions */ - for ( k = 0; k < *rank; k++ ) { - perm_dims[k] = (size_t)dims[*rank - k - 1]; - err |= Mul(&tmp, tmp, perm_dims[k]); - } - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - free(perm_dims); - perm_dims = NULL; - *rank = 0; - } - *nelems = (hsize_t)tmp; - H5Sclose(space_id); - } else { - hsize_t *dims = (hsize_t *)malloc(*rank * sizeof(hsize_t)); - if ( NULL != dims ) { - int k; - size_t tmp = 1; - (void)H5Sget_simple_extent_dims(space_id, dims, NULL); - /* Permute dimensions */ - for ( k = 0; k < *rank; k++ ) { - perm_dims[k] = (size_t)dims[*rank - k - 1]; - err |= Mul(&tmp, tmp, perm_dims[k]); - } - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - free(perm_dims); - perm_dims = NULL; - *rank = 0; - } - *nelems = (hsize_t)tmp; - free(dims); - H5Sclose(space_id); - } else { - free(perm_dims); - perm_dims = NULL; - *rank = 0; - H5Sclose(space_id); - Mat_Critical("Error allocating memory for dims"); - } - } - } else { - *rank = 0; - H5Sclose(space_id); - Mat_Critical("Error allocating memory for matvar->dims"); - } - - return perm_dims; -} - -static int -Mat_H5ReadFieldNames(matvar_t *matvar, hid_t dset_id, hsize_t *nfields) -{ - hsize_t i; - hid_t field_id, attr_id, space_id; - hvl_t *fieldnames_vl; - herr_t herr; - int err; - - attr_id = H5Aopen_by_name(dset_id, ".", "MATLAB_fields", H5P_DEFAULT, H5P_DEFAULT); - space_id = H5Aget_space(attr_id); - err = H5Sget_simple_extent_dims(space_id, nfields, NULL); - if ( err < 0 ) { - H5Sclose(space_id); - H5Aclose(attr_id); - return MATIO_E_GENERIC_READ_ERROR; - } else { - err = MATIO_E_NO_ERROR; - } - fieldnames_vl = (hvl_t *)calloc((size_t)(*nfields), sizeof(*fieldnames_vl)); - if ( fieldnames_vl == NULL ) { - H5Sclose(space_id); - H5Aclose(attr_id); - return MATIO_E_OUT_OF_MEMORY; - } - field_id = H5Aget_type(attr_id); - herr = H5Aread(attr_id, field_id, fieldnames_vl); - if ( herr >= 0 ) { - matvar->internal->num_fields = (unsigned int)*nfields; - matvar->internal->fieldnames = - (char **)calloc((size_t)(*nfields), sizeof(*matvar->internal->fieldnames)); - if ( matvar->internal->fieldnames != NULL ) { - for ( i = 0; i < *nfields; i++ ) { - matvar->internal->fieldnames[i] = (char *)calloc(fieldnames_vl[i].len + 1, 1); - if ( matvar->internal->fieldnames[i] != NULL ) { - if ( fieldnames_vl[i].p != NULL ) { - memcpy(matvar->internal->fieldnames[i], fieldnames_vl[i].p, - fieldnames_vl[i].len); - } - } else { - err = MATIO_E_OUT_OF_MEMORY; - break; - } - } - } else { - err = MATIO_E_OUT_OF_MEMORY; - } -#if H5_VERSION_GE(1, 12, 0) - H5Treclaim(field_id, space_id, H5P_DEFAULT, fieldnames_vl); -#else - H5Dvlen_reclaim(field_id, space_id, H5P_DEFAULT, fieldnames_vl); -#endif - } else { - err = MATIO_E_GENERIC_READ_ERROR; - } - - H5Sclose(space_id); - H5Tclose(field_id); - H5Aclose(attr_id); - free(fieldnames_vl); - - return err; -} - -static int -Mat_H5ReadDatasetInfo(mat_t *mat, matvar_t *matvar, hid_t dset_id) -{ - int err; - hsize_t nelems; - - err = Mat_H5ReadVarInfo(matvar, dset_id); - if ( err ) { - return err; - } - - matvar->dims = Mat_H5ReadDims(dset_id, &nelems, &matvar->rank); - if ( NULL == matvar->dims ) { - return MATIO_E_UNKNOWN_ERROR; - } - - /* Check for attribute that indicates an empty array */ - if ( H5Aexists_by_name(dset_id, ".", "MATLAB_empty", H5P_DEFAULT) ) { - int empty = 0; - herr_t herr; - hid_t attr_id = H5Aopen_by_name(dset_id, ".", "MATLAB_empty", H5P_DEFAULT, H5P_DEFAULT); - /* FIXME: Check that dataspace is scalar */ - herr = H5Aread(attr_id, H5T_NATIVE_INT, &empty); - H5Aclose(attr_id); - if ( herr < 0 ) { - err = MATIO_E_GENERIC_READ_ERROR; - } else if ( empty ) { - matvar->rank = (int)matvar->dims[0]; - free(matvar->dims); - matvar->dims = (size_t *)calloc(matvar->rank, sizeof(*matvar->dims)); - if ( matvar->dims == NULL ) { - err = MATIO_E_OUT_OF_MEMORY; - } else { - herr = - H5Dread(dset_id, SizeType2H5T(), H5S_ALL, H5S_ALL, H5P_DEFAULT, matvar->dims); - if ( herr < 0 ) { - err = MATIO_E_GENERIC_READ_ERROR; - } else { - size_t tmp = 1; - err = Mat_MulDims(matvar, &tmp); - nelems = (hsize_t)tmp; - } - } - } - if ( err ) { - return err; - } - } - - /* Test if dataset type is compound and if so if it's complex */ - { - hid_t type_id = H5Dget_type(dset_id); - if ( H5T_COMPOUND == H5Tget_class(type_id) ) { - /* FIXME: Any more checks? */ - matvar->isComplex = MAT_F_COMPLEX; - } - H5Tclose(type_id); - } - - /* Test if dataset is deflated */ - { - hid_t plist_id = H5Dget_create_plist(dset_id); - if ( plist_id > 0 ) { - const int nFilters = H5Pget_nfilters(plist_id); - int i; - for ( i = 0; i < nFilters; i++ ) { - const H5Z_filter_t filterType = - H5Pget_filter2(plist_id, i, NULL, NULL, 0, 0, NULL, NULL); - if ( H5Z_FILTER_DEFLATE == filterType ) { - matvar->compression = MAT_COMPRESSION_ZLIB; - break; - } - } - H5Pclose(plist_id); - } - } - - /* If the dataset is a cell array read the info of the cells */ - if ( MAT_C_CELL == matvar->class_type ) { - matvar_t **cells; - - matvar->data_size = sizeof(matvar_t **); - err = Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - matvar->data = calloc(matvar->nbytes, 1); - if ( NULL == matvar->data ) { - Mat_Critical("Couldn't allocate memory for the data"); - return MATIO_E_OUT_OF_MEMORY; - } - cells = (matvar_t **)matvar->data; - - if ( nelems ) { - hobj_ref_t *ref_ids = (hobj_ref_t *)calloc(nelems, sizeof(*ref_ids)); - if ( ref_ids != NULL ) { - size_t i; - herr_t herr = - H5Dread(dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, ref_ids); - if ( herr < 0 ) { - free(ref_ids); - return MATIO_E_GENERIC_READ_ERROR; - } - for ( i = 0; i < nelems; i++ ) { - hid_t ref_id; - cells[i] = Mat_VarCalloc(); - cells[i]->internal->hdf5_ref = ref_ids[i]; - /* Closing of ref_id is done in Mat_H5ReadNextReferenceInfo */ - ref_id = H5RDEREFERENCE(dset_id, H5R_OBJECT, ref_ids + i); - if ( ref_id < 0 ) { - err = MATIO_E_GENERIC_READ_ERROR; - } else { - cells[i]->internal->id = ref_id; - err = Mat_H5ReadNextReferenceInfo(ref_id, cells[i], mat); - } - if ( err ) { - break; - } - } - free(ref_ids); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - } else if ( MAT_C_STRUCT == matvar->class_type ) { - /* Empty structures can be a dataset */ - - /* Check if the structure defines its fields in MATLAB_fields */ - if ( H5Aexists_by_name(dset_id, ".", "MATLAB_fields", H5P_DEFAULT) ) { - hsize_t nfields; - err = Mat_H5ReadFieldNames(matvar, dset_id, &nfields); - } - } - - return err; -} - -static int -Mat_H5ReadGroupInfo(mat_t *mat, matvar_t *matvar, hid_t dset_id) -{ - int fields_are_variables = 1; - hsize_t nfields = 0, nelems; - hid_t attr_id, field_id; - matvar_t **fields; - H5O_type_t obj_type; - int err; - - err = Mat_H5ReadVarInfo(matvar, dset_id); - if ( err < 0 ) { - return err; - } - - /* Check if the variable is sparse */ - if ( H5Aexists_by_name(dset_id, ".", "MATLAB_sparse", H5P_DEFAULT) ) { - herr_t herr; - hid_t sparse_dset_id; - unsigned nrows = 0; - - attr_id = H5Aopen_by_name(dset_id, ".", "MATLAB_sparse", H5P_DEFAULT, H5P_DEFAULT); - herr = H5Aread(attr_id, H5T_NATIVE_UINT, &nrows); - H5Aclose(attr_id); - if ( herr < 0 ) { - return MATIO_E_GENERIC_READ_ERROR; - } - - matvar->class_type = MAT_C_SPARSE; - - sparse_dset_id = H5Dopen(dset_id, "jc", H5P_DEFAULT); - matvar->dims = Mat_H5ReadDims(sparse_dset_id, &nelems, &matvar->rank); - H5Dclose(sparse_dset_id); - if ( NULL != matvar->dims ) { - if ( 1 == matvar->rank ) { - size_t *dims = (size_t *)realloc(matvar->dims, 2 * sizeof(*matvar->dims)); - if ( NULL != dims ) { - matvar->rank = 2; - matvar->dims = dims; - } - } - if ( 2 == matvar->rank ) { - matvar->dims[1] = matvar->dims[0] - 1; - matvar->dims[0] = nrows; - } - } else { - return MATIO_E_UNKNOWN_ERROR; - } - - /* Test if dataset type is compound and if so if it's complex */ - if ( H5Lexists(dset_id, "data", H5P_DEFAULT) ) { - hid_t type_id; - sparse_dset_id = H5Dopen(dset_id, "data", H5P_DEFAULT); - type_id = H5Dget_type(sparse_dset_id); - if ( H5T_COMPOUND == H5Tget_class(type_id) ) { - /* FIXME: Any more checks? */ - matvar->isComplex = MAT_F_COMPLEX; - } - H5Tclose(type_id); - H5Dclose(sparse_dset_id); - } - return MATIO_E_NO_ERROR; - } - - if ( MAT_C_STRUCT != matvar->class_type ) { - return MATIO_E_GENERIC_READ_ERROR; - } - - /* Check if the structure defines its fields in MATLAB_fields */ - if ( H5Aexists_by_name(dset_id, ".", "MATLAB_fields", H5P_DEFAULT) ) { - err = Mat_H5ReadFieldNames(matvar, dset_id, &nfields); - if ( err ) { - return err; - } - } else { - herr_t herr; - H5G_info_t group_info; - matvar->internal->num_fields = 0; - group_info.nlinks = 0; - herr = H5Gget_info(dset_id, &group_info); - if ( herr >= 0 && group_info.nlinks > 0 ) { - struct ReadGroupInfoIterData group_data = {0, NULL}; - - /* First iteration to retrieve number of relevant links */ - herr = H5Literate_by_name(dset_id, matvar->internal->hdf5_name, H5_INDEX_NAME, - H5_ITER_NATIVE, NULL, Mat_H5ReadGroupInfoIterate, - (void *)&group_data, H5P_DEFAULT); - if ( herr > 0 && group_data.nfields > 0 ) { - matvar->internal->fieldnames = (char **)calloc( - (size_t)(group_data.nfields), sizeof(*matvar->internal->fieldnames)); - group_data.nfields = 0; - group_data.matvar = matvar; - if ( matvar->internal->fieldnames != NULL ) { - /* Second iteration to fill fieldnames */ - H5Literate_by_name(dset_id, matvar->internal->hdf5_name, H5_INDEX_NAME, - H5_ITER_NATIVE, NULL, Mat_H5ReadGroupInfoIterate, - (void *)&group_data, H5P_DEFAULT); - } - matvar->internal->num_fields = (unsigned)group_data.nfields; - nfields = group_data.nfields; - } - } - } - - if ( nfields > 0 ) { - H5O_INFO_T object_info; - object_info.type = H5O_TYPE_UNKNOWN; - H5OGET_INFO_BY_NAME(dset_id, matvar->internal->fieldnames[0], &object_info, H5P_DEFAULT); - obj_type = object_info.type; - } else { - obj_type = H5O_TYPE_UNKNOWN; - } - if ( obj_type == H5O_TYPE_DATASET ) { - hid_t field_type_id; - field_id = H5Dopen(dset_id, matvar->internal->fieldnames[0], H5P_DEFAULT); - field_type_id = H5Dget_type(field_id); - if ( H5T_REFERENCE == H5Tget_class(field_type_id) ) { - /* Check if the field has the MATLAB_class attribute. If so, it - * means the structure is a scalar. Otherwise, the dimensions of - * the field dataset is the dimensions of the structure - */ - if ( H5Aexists_by_name(field_id, ".", "MATLAB_class", H5P_DEFAULT) ) { - matvar->rank = 2; - matvar->dims = (size_t *)malloc(2 * sizeof(*matvar->dims)); - if ( NULL != matvar->dims ) { - matvar->dims[0] = 1; - matvar->dims[1] = 1; - nelems = 1; - } else { - H5Tclose(field_type_id); - H5Dclose(field_id); - Mat_Critical("Error allocating memory for matvar->dims"); - return MATIO_E_OUT_OF_MEMORY; - } - } else { - matvar->dims = Mat_H5ReadDims(field_id, &nelems, &matvar->rank); - if ( NULL != matvar->dims ) { - fields_are_variables = 0; - } else { - H5Tclose(field_type_id); - H5Dclose(field_id); - return MATIO_E_UNKNOWN_ERROR; - } - } - } else { - /* Structure should be a scalar */ - matvar->rank = 2; - matvar->dims = (size_t *)malloc(2 * sizeof(*matvar->dims)); - if ( NULL != matvar->dims ) { - matvar->dims[0] = 1; - matvar->dims[1] = 1; - nelems = 1; - } else { - H5Tclose(field_type_id); - H5Dclose(field_id); - Mat_Critical("Error allocating memory for matvar->dims"); - return MATIO_E_UNKNOWN_ERROR; - } - } - H5Tclose(field_type_id); - H5Dclose(field_id); - } else { - /* Structure should be a scalar */ - matvar->rank = 2; - matvar->dims = (size_t *)malloc(2 * sizeof(*matvar->dims)); - if ( NULL != matvar->dims ) { - matvar->dims[0] = 1; - matvar->dims[1] = 1; - nelems = 1; - } else { - Mat_Critical("Error allocating memory for matvar->dims"); - return MATIO_E_OUT_OF_MEMORY; - } - } - - if ( nelems < 1 || nfields < 1 ) - return err; - - matvar->data_size = sizeof(*fields); - { - size_t nelems_x_nfields; - err = Mul(&nelems_x_nfields, nelems, nfields); - err |= Mul(&matvar->nbytes, nelems_x_nfields, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - matvar->nbytes = 0; - return err; - } - } - fields = (matvar_t **)calloc(matvar->nbytes, 1); - matvar->data = fields; - if ( NULL != fields ) { - hsize_t k; - for ( k = 0; k < nfields; k++ ) { - H5O_INFO_T object_info; - fields[k] = NULL; - object_info.type = H5O_TYPE_UNKNOWN; - H5OGET_INFO_BY_NAME(dset_id, matvar->internal->fieldnames[k], &object_info, - H5P_DEFAULT); - if ( object_info.type == H5O_TYPE_DATASET ) { - field_id = H5Dopen(dset_id, matvar->internal->fieldnames[k], H5P_DEFAULT); - if ( !fields_are_variables ) { - hobj_ref_t *ref_ids = (hobj_ref_t *)calloc((size_t)nelems, sizeof(*ref_ids)); - if ( ref_ids != NULL ) { - hsize_t l; - herr_t herr = H5Dread(field_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, - H5P_DEFAULT, ref_ids); - if ( herr < 0 ) { - err = MATIO_E_GENERIC_READ_ERROR; - } else { - for ( l = 0; l < nelems; l++ ) { - hid_t ref_id; - fields[l * nfields + k] = Mat_VarCalloc(); - fields[l * nfields + k]->name = - Mat_strdup(matvar->internal->fieldnames[k]); - fields[l * nfields + k]->internal->hdf5_ref = ref_ids[l]; - /* Closing of ref_id is done in Mat_H5ReadNextReferenceInfo */ - ref_id = H5RDEREFERENCE(field_id, H5R_OBJECT, ref_ids + l); - if ( ref_id < 0 ) { - err = MATIO_E_GENERIC_READ_ERROR; - } else { - fields[l * nfields + k]->internal->id = ref_id; - err = Mat_H5ReadNextReferenceInfo(ref_id, - fields[l * nfields + k], mat); - } - if ( err ) { - break; - } - } - } - free(ref_ids); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } else { - fields[k] = Mat_VarCalloc(); - fields[k]->name = Mat_strdup(matvar->internal->fieldnames[k]); - err = Mat_H5ReadDatasetInfo(mat, fields[k], field_id); - } - H5Dclose(field_id); - } else if ( object_info.type == H5O_TYPE_GROUP ) { - field_id = H5Gopen(dset_id, matvar->internal->fieldnames[k], H5P_DEFAULT); - if ( -1 < field_id ) { - fields[k] = Mat_VarCalloc(); - fields[k]->name = Mat_strdup(matvar->internal->fieldnames[k]); - err = Mat_H5ReadGroupInfo(mat, fields[k], field_id); - H5Gclose(field_id); - } - } - if ( err ) { - break; - } - } - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - - return err; -} - -static herr_t -Mat_H5ReadGroupInfoIterate(hid_t dset_id, const char *name, const H5L_info_t *info, void *op_data) -{ - matvar_t *matvar; - H5O_INFO_T object_info; - struct ReadGroupInfoIterData *group_data; - - /* FIXME: follow symlinks, datatypes? */ - - object_info.type = H5O_TYPE_UNKNOWN; - H5OGET_INFO_BY_NAME(dset_id, name, &object_info, H5P_DEFAULT); - if ( H5O_TYPE_DATASET != object_info.type && H5O_TYPE_GROUP != object_info.type ) - return 0; - - group_data = (struct ReadGroupInfoIterData *)op_data; - if ( group_data == NULL ) - return -1; - matvar = group_data->matvar; - - switch ( object_info.type ) { - case H5O_TYPE_GROUP: - /* Check that this is not the /#refs# group */ - if ( 0 == strcmp(name, "#refs#") ) - return 0; - /* Fall through */ - case H5O_TYPE_DATASET: - if ( matvar != NULL ) { - matvar->internal->fieldnames[group_data->nfields] = Mat_strdup(name); - } - group_data->nfields++; - break; - default: - /* Not possible to get here */ - break; - } - - return 1; -} - -static int -Mat_H5ReadNextReferenceInfo(hid_t ref_id, matvar_t *matvar, mat_t *mat) -{ - int err; - if ( ref_id < 0 || matvar == NULL ) - return MATIO_E_NO_ERROR; - - switch ( H5Iget_type(ref_id) ) { - case H5I_DATASET: - err = Mat_H5ReadDatasetInfo(mat, matvar, ref_id); - if ( matvar->internal->id != ref_id ) { - /* Close dataset and increment count */ - H5Dclose(ref_id); - } - - /*H5Dclose(ref_id);*/ - break; - - case H5I_GROUP: - err = Mat_H5ReadGroupInfo(mat, matvar, ref_id); - break; - - default: - err = MATIO_E_NO_ERROR; - break; - } - - return err; -} - -static int -Mat_H5ReadData(hid_t dset_id, hid_t h5_type, hid_t mem_space, hid_t dset_space, int isComplex, - void *data) -{ - herr_t herr; - - if ( !isComplex ) { - herr = H5Dread(dset_id, h5_type, mem_space, dset_space, H5P_DEFAULT, data); - if ( herr < 0 ) { - return MATIO_E_GENERIC_READ_ERROR; - } - } else { - mat_complex_split_t *complex_data = (mat_complex_split_t *)data; - hid_t h5_complex; - size_t h5_size = H5Tget_size(h5_type); - - h5_complex = H5Tcreate(H5T_COMPOUND, h5_size); - H5Tinsert(h5_complex, "real", 0, h5_type); - herr = H5Dread(dset_id, h5_complex, mem_space, dset_space, H5P_DEFAULT, complex_data->Re); - H5Tclose(h5_complex); - if ( herr < 0 ) { - return MATIO_E_GENERIC_READ_ERROR; - } - - h5_complex = H5Tcreate(H5T_COMPOUND, h5_size); - H5Tinsert(h5_complex, "imag", 0, h5_type); - herr = H5Dread(dset_id, h5_complex, mem_space, dset_space, H5P_DEFAULT, complex_data->Im); - H5Tclose(h5_complex); - if ( herr < 0 ) { - return MATIO_E_GENERIC_READ_ERROR; - } - } - - return MATIO_E_NO_ERROR; -} - -static int -Mat_H5ReadNextReferenceData(hid_t ref_id, matvar_t *matvar, mat_t *mat) -{ - int err = MATIO_E_NO_ERROR; - size_t nelems = 1; - - if ( ref_id < 0 || matvar == NULL ) - return err; - - /* If the datatype with references is a cell, we've already read info into - * the variable data, so just loop over each cell element and call - * Mat_H5ReadNextReferenceData on it. - */ - if ( MAT_C_CELL == matvar->class_type ) { - size_t i; - matvar_t **cells; - - if ( NULL == matvar->data ) { - return err; - } - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - return err; - } - cells = (matvar_t **)matvar->data; - for ( i = 0; i < nelems; i++ ) { - if ( NULL != cells[i] ) { - err = Mat_H5ReadNextReferenceData(cells[i]->internal->id, cells[i], mat); - } - if ( err ) { - break; - } - } - return err; - } - - switch ( H5Iget_type(ref_id) ) { - case H5I_DATASET: { - hid_t data_type_id, dset_id; - if ( MAT_C_CHAR == matvar->class_type ) { - matvar->data_type = MAT_T_UINT8; - matvar->data_size = (int)Mat_SizeOf(MAT_T_UINT8); - data_type_id = DataType2H5T(MAT_T_UINT8); - } else if ( MAT_C_STRUCT == matvar->class_type ) { - /* Empty structure array */ - break; - } else { - matvar->data_size = (int)Mat_SizeOfClass(matvar->class_type); - data_type_id = ClassType2H5T(matvar->class_type); - } - - err = Mat_MulDims(matvar, &nelems); - err |= Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err || matvar->nbytes < 1 ) { - H5Dclose(ref_id); - break; - } - - dset_id = ref_id; - - if ( !matvar->isComplex ) { - matvar->data = malloc(matvar->nbytes); - } else { - matvar->data = ComplexMalloc(matvar->nbytes); - } - if ( NULL != matvar->data ) { - err = Mat_H5ReadData(dset_id, data_type_id, H5S_ALL, H5S_ALL, matvar->isComplex, - matvar->data); - } - H5Dclose(dset_id); - break; - } - case H5I_GROUP: { - if ( MAT_C_SPARSE == matvar->class_type ) { - err = Mat_VarRead73(mat, matvar); - } else { - matvar_t **fields; - size_t i; - - if ( !matvar->nbytes || !matvar->data_size || NULL == matvar->data ) - break; - nelems = matvar->nbytes / matvar->data_size; - fields = (matvar_t **)matvar->data; - for ( i = 0; i < nelems; i++ ) { - if ( NULL != fields[i] && 0 < fields[i]->internal->hdf5_ref && - -1 < fields[i]->internal->id ) { - /* Dataset of references */ - err = Mat_H5ReadNextReferenceData(fields[i]->internal->id, fields[i], mat); - } else { - err = Mat_VarRead73(mat, fields[i]); - } - if ( err ) { - break; - } - } - } - break; - } - default: - break; - } - - return err; -} - -static int -Mat_H5WriteData(hid_t dset_id, hid_t h5_type, hid_t mem_space, hid_t dset_space, int isComplex, - void *data) -{ - int err = MATIO_E_NO_ERROR; - - if ( !isComplex ) { - if ( 0 > H5Dwrite(dset_id, h5_type, mem_space, dset_space, H5P_DEFAULT, data) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - } else { - mat_complex_split_t *complex_data = (mat_complex_split_t *)data; - hid_t h5_complex; - size_t h5_size = H5Tget_size(h5_type); - - /* Write real part of dataset */ - h5_complex = H5Tcreate(H5T_COMPOUND, h5_size); - H5Tinsert(h5_complex, "real", 0, h5_type); - err = Mat_H5WriteData(dset_id, h5_complex, mem_space, dset_space, 0, complex_data->Re); - H5Tclose(h5_complex); - - /* Write imaginary part of dataset */ - h5_complex = H5Tcreate(H5T_COMPOUND, h5_size); - H5Tinsert(h5_complex, "imag", 0, h5_type); - err += Mat_H5WriteData(dset_id, h5_complex, mem_space, dset_space, 0, complex_data->Im); - H5Tclose(h5_complex); - } - - return err; -} - -static int -Mat_H5WriteAppendData(hid_t id, hid_t h5_type, int mrank, const char *name, const size_t *mdims, - hsize_t *dims, int dim, int isComplex, void *data) -{ - int err = MATIO_E_NO_ERROR; - hid_t dset_id, space_id; - int rank; - - if ( dim < 1 || dim > mrank ) - return MATIO_E_BAD_ARGUMENT; - - dset_id = H5Dopen(id, name, H5P_DEFAULT); - space_id = H5Dget_space(dset_id); - rank = H5Sget_simple_extent_ndims(space_id); - if ( rank == mrank ) { - hsize_t *size_offset_dims; - size_offset_dims = (hsize_t *)malloc(rank * sizeof(*size_offset_dims)); - if ( NULL != size_offset_dims ) { - hsize_t offset; - hid_t mspace_id; - int k; - - (void)H5Sget_simple_extent_dims(space_id, size_offset_dims, NULL); - offset = size_offset_dims[rank - dim]; - size_offset_dims[rank - dim] += mdims[dim - 1]; - H5Dset_extent(dset_id, size_offset_dims); - for ( k = 0; k < rank; k++ ) { - size_offset_dims[k] = 0; - } - size_offset_dims[rank - dim] = offset; - /* Need to reopen */ - H5Sclose(space_id); - space_id = H5Dget_space(dset_id); - H5Sselect_hyperslab(space_id, H5S_SELECT_SET, size_offset_dims, NULL, dims, NULL); - free(size_offset_dims); - mspace_id = H5Screate_simple(rank, dims, NULL); - err = Mat_H5WriteData(dset_id, h5_type, mspace_id, space_id, isComplex, data); - H5Sclose(mspace_id); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } else { - err = MATIO_E_GENERIC_WRITE_ERROR; - } - H5Sclose(space_id); - H5Dclose(dset_id); - - return err; -} - -static int -Mat_VarWriteRef(hid_t id, matvar_t *matvar, enum matio_compression compression, hid_t *refs_id, - hobj_ref_t *ref) -{ - int err; - herr_t herr; - char obj_name[64]; - H5G_info_t group_info; - - group_info.nlinks = 0; - herr = H5Gget_info(*refs_id, &group_info); - if ( herr < 0 ) { - err = MATIO_E_BAD_ARGUMENT; - } else { - sprintf(obj_name, "%llu", group_info.nlinks); - if ( NULL != matvar ) - matvar->compression = compression; - err = Mat_VarWriteNext73(*refs_id, matvar, obj_name, refs_id); - sprintf(obj_name, "/#refs#/%llu", group_info.nlinks); - H5Rcreate(ref, id, obj_name, H5R_OBJECT, -1); - } - return err; -} - -static int -Mat_VarWriteEmpty(hid_t id, matvar_t *matvar, const char *name, const char *class_name) -{ - int err = MATIO_E_NO_ERROR; - hsize_t rank = matvar->rank; - unsigned empty = 1; - hid_t mspace_id, dset_id, attr_type_id, aspace_id, attr_id; - - mspace_id = H5Screate_simple(1, &rank, NULL); - dset_id = - H5Dcreate(id, name, H5T_NATIVE_HSIZE, mspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - attr_type_id = H5Tcopy(H5T_C_S1); - H5Tset_size(attr_type_id, strlen(class_name)); - aspace_id = H5Screate(H5S_SCALAR); - attr_id = H5Acreate(dset_id, "MATLAB_class", attr_type_id, aspace_id, H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, attr_type_id, class_name) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - H5Tclose(attr_type_id); - - if ( MATIO_E_NO_ERROR == err ) { - if ( 0 == strcmp(class_name, "struct") ) { - /* Write the fields attribute */ - hsize_t nfields = matvar->internal->num_fields; - if ( nfields ) { - hvl_t *fieldnames = (hvl_t *)malloc((size_t)nfields * sizeof(*fieldnames)); - if ( NULL != fieldnames ) { - hid_t str_type_id, fieldnames_id; - hsize_t k; - - str_type_id = H5Tcopy(H5T_C_S1); - for ( k = 0; k < nfields; k++ ) { - fieldnames[k].len = strlen(matvar->internal->fieldnames[k]); - fieldnames[k].p = matvar->internal->fieldnames[k]; - } - H5Tset_size(str_type_id, 1); - fieldnames_id = H5Tvlen_create(str_type_id); - aspace_id = H5Screate_simple(1, &nfields, NULL); - attr_id = H5Acreate(dset_id, "MATLAB_fields", fieldnames_id, aspace_id, - H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, fieldnames_id, fieldnames) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Aclose(attr_id); - H5Sclose(aspace_id); - H5Tclose(fieldnames_id); - H5Tclose(str_type_id); - free(fieldnames); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - } else if ( 0 == strcmp(class_name, "logical") ) { - /* Write the MATLAB_int_decode attribute */ - int int_decode = 1; - aspace_id = H5Screate(H5S_SCALAR); - attr_id = H5Acreate(dset_id, "MATLAB_int_decode", H5T_NATIVE_INT, aspace_id, - H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, H5T_NATIVE_INT, &int_decode) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - } - - if ( MATIO_E_NO_ERROR == err ) { - /* Write the empty attribute */ - aspace_id = H5Screate(H5S_SCALAR); - attr_id = H5Acreate(dset_id, "MATLAB_empty", H5T_NATIVE_UINT, aspace_id, H5P_DEFAULT, - H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, H5T_NATIVE_UINT, &empty) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - } - - if ( MATIO_E_NO_ERROR == err ) { - /* Write the dimensions as the data */ - if ( 0 > - H5Dwrite(dset_id, SizeType2H5T(), H5S_ALL, H5S_ALL, H5P_DEFAULT, matvar->dims) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - } - } - H5Dclose(dset_id); - H5Sclose(mspace_id); - - return err; -} - -/** @if mat_devman - * @brief Writes a cell array matlab variable to the specified HDF id with the - * given name - * - * @ingroup mat_internal - * @param id HDF id of the parent object - * @param matvar pointer to the cell array variable - * @param name Name of the HDF dataset - * @param refs_id pointer to the id of the /#refs# group in HDF5 - * @param dims array of permuted dimensions - * @retval 0 on success - * @endif - */ -static int -Mat_VarWriteCell73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, hsize_t *dims) -{ - int k; - hsize_t nelems = 1, l; - matvar_t **cells; - int err = MATIO_E_NO_ERROR; - - cells = (matvar_t **)matvar->data; - for ( k = 0; k < matvar->rank; k++ ) - nelems *= dims[k]; - - if ( 0 == nelems || NULL == matvar->data ) { - err = Mat_VarWriteEmpty(id, matvar, name, ClassNames[matvar->class_type]); - } else { - if ( *refs_id < 0 ) { - if ( H5Lexists(id, "/#refs#", H5P_DEFAULT) ) { - *refs_id = H5Gopen(id, "/#refs#", H5P_DEFAULT); - } else { - *refs_id = H5Gcreate(id, "/#refs#", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - } - } - if ( *refs_id > -1 ) { - hobj_ref_t *refs = (hobj_ref_t *)malloc((size_t)nelems * sizeof(*refs)); - if ( NULL != refs ) { - hid_t mspace_id = H5Screate_simple(matvar->rank, dims, NULL); - hid_t dset_id = H5Dcreate(id, name, H5T_STD_REF_OBJ, mspace_id, H5P_DEFAULT, - H5P_DEFAULT, H5P_DEFAULT); - - for ( l = 0; l < nelems; l++ ) { - err = Mat_VarWriteRef(id, cells[l], matvar->compression, refs_id, refs + l); - if ( err ) - break; - } - if ( MATIO_E_NO_ERROR == err ) { - err = Mat_H5WriteData(dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, 0, refs); - - if ( MATIO_E_NO_ERROR == err ) { - hid_t attr_id, aspace_id; - hid_t str_type_id = H5Tcopy(H5T_C_S1); - H5Tset_size(str_type_id, 4); - aspace_id = H5Screate(H5S_SCALAR); - attr_id = H5Acreate(dset_id, "MATLAB_class", str_type_id, aspace_id, - H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, str_type_id, "cell") ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Aclose(attr_id); - H5Sclose(aspace_id); - H5Tclose(str_type_id); - } - } - H5Dclose(dset_id); - free(refs); - H5Sclose(mspace_id); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } else { - err = MATIO_E_OUTPUT_BAD_DATA; - } - } - - return err; -} - -/** @if mat_devman - * @brief Writes a character matlab variable to the specified HDF id with the - * given name - * - * @ingroup mat_internal - * @param id HDF id of the parent object - * @param matvar pointer to the character variable - * @param name Name of the HDF dataset - * @param dims array of permuted dimensions - * @retval 0 on success - * @endif - */ -static int -Mat_VarWriteChar73(hid_t id, matvar_t *matvar, const char *name, hsize_t *dims) -{ - int err = MATIO_E_NO_ERROR, k; - hsize_t nelems = 1; - mat_uint16_t *u16 = NULL; - hid_t h5type; - - for ( k = 0; k < matvar->rank; k++ ) { - nelems *= dims[k]; - } - - if ( 0 == nelems || NULL == matvar->data ) { - err = Mat_VarWriteEmpty(id, matvar, name, ClassNames[matvar->class_type]); - } else { - int matlab_int_decode = 2; - hid_t mspace_id, dset_id, attr_type_id, attr_id, aspace_id; - - mspace_id = H5Screate_simple(matvar->rank, dims, NULL); - switch ( matvar->data_type ) { - case MAT_T_UTF32: - case MAT_T_INT32: - case MAT_T_UINT32: - /* Not sure matlab will actually handle this */ - dset_id = H5Dcreate(id, name, ClassType2H5T(MAT_C_UINT32), mspace_id, H5P_DEFAULT, - H5P_DEFAULT, H5P_DEFAULT); - break; - case MAT_T_UTF16: - case MAT_T_UTF8: - case MAT_T_INT16: - case MAT_T_UINT16: - case MAT_T_INT8: - case MAT_T_UINT8: - dset_id = H5Dcreate(id, name, ClassType2H5T(MAT_C_UINT16), mspace_id, H5P_DEFAULT, - H5P_DEFAULT, H5P_DEFAULT); - break; - default: - H5Sclose(mspace_id); - return MATIO_E_OUTPUT_BAD_DATA; - } - attr_type_id = H5Tcopy(H5T_C_S1); - H5Tset_size(attr_type_id, strlen(ClassNames[matvar->class_type])); - aspace_id = H5Screate(H5S_SCALAR); - attr_id = - H5Acreate(dset_id, "MATLAB_class", attr_type_id, aspace_id, H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, attr_type_id, ClassNames[matvar->class_type]) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Aclose(attr_id); - H5Tclose(attr_type_id); - - if ( MATIO_E_NO_ERROR == err ) { - attr_type_id = H5Tcopy(H5T_NATIVE_INT); - attr_id = H5Acreate(dset_id, "MATLAB_int_decode", attr_type_id, aspace_id, H5P_DEFAULT, - H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, attr_type_id, &matlab_int_decode) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Aclose(attr_id); - H5Tclose(attr_type_id); - } - H5Sclose(aspace_id); - - h5type = DataType2H5T(matvar->data_type); - if ( MATIO_E_NO_ERROR == err && matvar->data_type == MAT_T_UTF8 ) { - /* Convert to UTF-16 */ - h5type = H5T_NATIVE_UINT16; - u16 = (mat_uint16_t *)calloc(nelems, sizeof(mat_uint16_t)); - if ( u16 != NULL ) { - mat_uint8_t *data = (mat_uint8_t *)matvar->data; - size_t i, j = 0; - for ( i = 0; i < matvar->nbytes; i++ ) { - const mat_uint8_t c = data[i]; - if ( c <= 0x7F ) { /* ASCII */ - u16[j] = (mat_uint16_t)c; - } else if ( c < 0xE0 && i + 1 < matvar->nbytes ) { /* Extended ASCII */ - const mat_uint16_t _a = (mat_uint16_t)(c & 0x1F); - const mat_uint16_t _b = (mat_uint16_t)(data[i + 1] & 0x3F); - u16[j] = (_a << 6) | _b; - i = i + 1; - } else if ( (c & 0xF0) == 0xE0 && i + 2 < matvar->nbytes ) { /* BMP */ - const mat_uint16_t _a = (mat_uint16_t)(c & 0xF); - const mat_uint16_t _b = (mat_uint16_t)(data[i + 1] & 0x3C) >> 2; - const mat_uint16_t _c = (mat_uint16_t)(data[i + 1] & 0x3); - const mat_uint16_t _d = (mat_uint16_t)(data[i + 2] & 0x30) >> 4; - const mat_uint16_t _e = (mat_uint16_t)(data[i + 2] & 0xF); - u16[j] = (_a << 12) | (_b << 8) | (_c << 6) | (_d << 4) | _e; - i = i + 2; - } else { /* Full UTF-8 */ - err = MATIO_E_OPERATION_NOT_SUPPORTED; - break; - } - j++; - } - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - - if ( MATIO_E_NO_ERROR == err ) { - void *data = matvar->data_type == MAT_T_UTF8 ? u16 : matvar->data; - if ( 0 > H5Dwrite(dset_id, h5type, H5S_ALL, H5S_ALL, H5P_DEFAULT, (void *)data) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - } - free(u16); - H5Dclose(dset_id); - H5Sclose(mspace_id); - } - - return err; -} - -static int -Mat_WriteEmptyVariable73(hid_t id, const char *name, hsize_t rank, size_t *dims) -{ - int err = MATIO_E_NO_ERROR; - unsigned empty = 1; - hid_t mspace_id, dset_id; - - mspace_id = H5Screate_simple(1, &rank, NULL); - dset_id = - H5Dcreate(id, name, H5T_NATIVE_HSIZE, mspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - if ( dset_id > -1 ) { - hid_t attr_type_id, attr_id, aspace_id; - - attr_type_id = H5Tcopy(H5T_C_S1); - H5Tset_size(attr_type_id, 6); - aspace_id = H5Screate(H5S_SCALAR); - attr_id = - H5Acreate(dset_id, "MATLAB_class", attr_type_id, aspace_id, H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, attr_type_id, "double") ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - H5Tclose(attr_type_id); - - if ( MATIO_E_NO_ERROR == err ) { - aspace_id = H5Screate(H5S_SCALAR); - attr_id = H5Acreate(dset_id, "MATLAB_empty", H5T_NATIVE_UINT, aspace_id, H5P_DEFAULT, - H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, H5T_NATIVE_UINT, &empty) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - } - - if ( MATIO_E_NO_ERROR == err ) { - /* Write the dimensions as the data */ - if ( 0 > H5Dwrite(dset_id, SizeType2H5T(), H5S_ALL, H5S_ALL, H5P_DEFAULT, dims) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - } - H5Dclose(dset_id); - } else { - err = MATIO_E_OUTPUT_BAD_DATA; - } - H5Sclose(mspace_id); - - return err; -} - -/** @if mat_devman - * @brief Writes a logical matlab variable to the specified HDF id with the - * given name - * - * @ingroup mat_internal - * @param id HDF id of the parent object - * @param matvar pointer to the logical variable - * @param name Name of the HDF dataset - * @param dims array of permuted dimensions - * @retval 0 on success - * @endif - */ -static int -Mat_VarWriteLogical73(hid_t id, matvar_t *matvar, const char *name, hsize_t *dims) -{ - int err = MATIO_E_NO_ERROR, k; - hsize_t nelems = 1; - hid_t plist; - - for ( k = 0; k < matvar->rank; k++ ) { - nelems *= dims[k]; - } - - if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { - plist = H5Pcreate(H5P_DATASET_CREATE); - if ( MAX_RANK >= matvar->rank ) { - hsize_t chunk_dims[MAX_RANK]; - Mat_H5GetChunkSize(matvar->rank, dims, chunk_dims); - H5Pset_chunk(plist, matvar->rank, chunk_dims); - } else { - hsize_t *chunk_dims = (hsize_t *)malloc(matvar->rank * sizeof(hsize_t)); - if ( NULL != chunk_dims ) { - Mat_H5GetChunkSize(matvar->rank, dims, chunk_dims); - H5Pset_chunk(plist, matvar->rank, chunk_dims); - free(chunk_dims); - } else { - H5Pclose(plist); - return MATIO_E_OUT_OF_MEMORY; - } - } - H5Pset_deflate(plist, 9); - } else { - plist = H5P_DEFAULT; - } - - if ( 0 == nelems || NULL == matvar->data ) { - err = Mat_VarWriteEmpty(id, matvar, name, "logical"); - } else { - int int_decode = 1; - hid_t mspace_id, dset_id, attr_type_id, attr_id, aspace_id; - - mspace_id = H5Screate_simple(matvar->rank, dims, NULL); - /* Note that MATLAB only recognizes uint8 as logical */ - dset_id = H5Dcreate(id, name, ClassType2H5T(MAT_C_UINT8), mspace_id, H5P_DEFAULT, plist, - H5P_DEFAULT); - attr_type_id = H5Tcopy(H5T_C_S1); - H5Tset_size(attr_type_id, 7); - aspace_id = H5Screate(H5S_SCALAR); - attr_id = - H5Acreate(dset_id, "MATLAB_class", attr_type_id, aspace_id, H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, attr_type_id, "logical") ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - H5Tclose(attr_type_id); - - if ( MATIO_E_NO_ERROR == err ) { - /* Write the MATLAB_int_decode attribute */ - aspace_id = H5Screate(H5S_SCALAR); - attr_id = H5Acreate(dset_id, "MATLAB_int_decode", H5T_NATIVE_INT, aspace_id, - H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, H5T_NATIVE_INT, &int_decode) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - } - - if ( MATIO_E_NO_ERROR == err ) { - if ( 0 > H5Dwrite(dset_id, DataType2H5T(matvar->data_type), H5S_ALL, H5S_ALL, - H5P_DEFAULT, matvar->data) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - } - H5Dclose(dset_id); - H5Sclose(mspace_id); - } - - if ( H5P_DEFAULT != plist ) - H5Pclose(plist); - - return err; -} - -/** @if mat_devman - * @brief Writes a numeric matlab variable to the specified HDF id with the - * given name - * - * @ingroup mat_internal - * @param id HDF id of the parent object - * @param matvar pointer to the numeric variable - * @param name Name of the HDF dataset - * @param dims array of permuted dimensions - * @param max_dims maximum dimensions - * @retval 0 on success - * @endif - */ -static int -Mat_VarWriteNumeric73(hid_t id, matvar_t *matvar, const char *name, hsize_t *dims, - hsize_t *max_dims) -{ - int err = MATIO_E_NO_ERROR, k; - hsize_t nelems = 1; - hid_t plist; - - for ( k = 0; k < matvar->rank; k++ ) { - nelems *= dims[k]; - } - - if ( matvar->compression || NULL != max_dims ) { - plist = H5Pcreate(H5P_DATASET_CREATE); - if ( MAX_RANK >= matvar->rank ) { - hsize_t chunk_dims[MAX_RANK]; - Mat_H5GetChunkSize(matvar->rank, dims, chunk_dims); - H5Pset_chunk(plist, matvar->rank, chunk_dims); - } else { - hsize_t *chunk_dims = (hsize_t *)malloc(matvar->rank * sizeof(hsize_t)); - if ( NULL != chunk_dims ) { - Mat_H5GetChunkSize(matvar->rank, dims, chunk_dims); - H5Pset_chunk(plist, matvar->rank, chunk_dims); - free(chunk_dims); - } else { - H5Pclose(plist); - return MATIO_E_OUT_OF_MEMORY; - } - } - if ( matvar->compression == MAT_COMPRESSION_ZLIB ) - H5Pset_deflate(plist, 9); - } else { - plist = H5P_DEFAULT; - } - - if ( 0 == nelems || NULL == matvar->data ) { - err = Mat_VarWriteEmpty(id, matvar, name, ClassNames[matvar->class_type]); - } else { - hid_t mspace_id, dset_id, attr_type_id, attr_id, aspace_id; - hid_t h5_type = ClassType2H5T(matvar->class_type); - hid_t h5_dtype = DataType(h5_type, matvar->isComplex); - - mspace_id = H5Screate_simple(matvar->rank, dims, max_dims); - dset_id = H5Dcreate(id, name, h5_dtype, mspace_id, H5P_DEFAULT, plist, H5P_DEFAULT); - attr_type_id = H5Tcopy(H5T_C_S1); - H5Tset_size(attr_type_id, strlen(ClassNames[matvar->class_type])); - aspace_id = H5Screate(H5S_SCALAR); - attr_id = - H5Acreate(dset_id, "MATLAB_class", attr_type_id, aspace_id, H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, attr_type_id, ClassNames[matvar->class_type]) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - H5Tclose(attr_type_id); - H5Tclose(h5_dtype); - if ( MATIO_E_NO_ERROR == err ) { - err = Mat_H5WriteData(dset_id, h5_type, H5S_ALL, H5S_ALL, matvar->isComplex, - matvar->data); - } - H5Dclose(dset_id); - H5Sclose(mspace_id); - } - - if ( H5P_DEFAULT != plist ) - H5Pclose(plist); - - return err; -} - -/** @if mat_devman - * @brief Writes/appends a numeric matlab variable to the specified HDF id with the - * given name - * - * @ingroup mat_internal - * @param id HDF id of the parent object - * @param matvar pointer to the numeric variable - * @param name Name of the HDF dataset - * @param dims array of permuted dimensions - * @param dim dimension to append data - * @retval 0 on success - * @endif - */ -static int -Mat_VarWriteAppendNumeric73(hid_t id, matvar_t *matvar, const char *name, hsize_t *dims, int dim) -{ - int err = MATIO_E_NO_ERROR, k; - hsize_t nelems = 1; - - for ( k = 0; k < matvar->rank; k++ ) { - nelems *= dims[k]; - } - - if ( 0 != nelems && NULL != matvar->data ) { - if ( H5Lexists(id, matvar->name, H5P_DEFAULT) ) { - err = Mat_H5WriteAppendData(id, ClassType2H5T(matvar->class_type), matvar->rank, - matvar->name, matvar->dims, dims, dim, matvar->isComplex, - matvar->data); - } else { - /* Create with unlimited number of dimensions */ - if ( MAX_RANK >= matvar->rank ) { - hsize_t max_dims[MAX_RANK]; - for ( k = 0; k < matvar->rank; k++ ) { - max_dims[k] = H5S_UNLIMITED; - } - err = Mat_VarWriteNumeric73(id, matvar, name, dims, max_dims); - } else { - hsize_t *max_dims = (hsize_t *)malloc(matvar->rank * sizeof(hsize_t)); - if ( NULL != max_dims ) { - for ( k = 0; k < matvar->rank; k++ ) { - max_dims[k] = H5S_UNLIMITED; - } - err = Mat_VarWriteNumeric73(id, matvar, name, dims, max_dims); - free(max_dims); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - } - } else { - err = MATIO_E_OUTPUT_BAD_DATA; - } - - return err; -} - -/** @if mat_devman - * @brief Writes a sparse matrix variable to the specified HDF id with the - * given name - * - * @ingroup mat_internal - * @param id HDF id of the parent object - * @param matvar pointer to the structure variable - * @param name Name of the HDF dataset - * @retval 0 on success - * @endif - */ -static int -Mat_VarWriteSparse73(hid_t id, matvar_t *matvar, const char *name) -{ - int err = MATIO_E_NO_ERROR; - hid_t sparse_id; - - sparse_id = H5Gcreate(id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - if ( sparse_id < 0 ) { - Mat_Critical("Error creating group for sparse array %s", matvar->name); - err = MATIO_E_OUTPUT_BAD_DATA; - } else { - hid_t size_type_id, h5_type, h5_dtype; - hid_t mspace_id, dset_id, attr_type_id, attr_id, aspace_id; - mat_sparse_t *sparse; - hsize_t nir, njc, ndata; - mat_uint64_t sparse_attr_value; - enum matio_classes class_type; - - sparse = (mat_sparse_t *)matvar->data; - class_type = DataType2ClassType(matvar->data_type); - attr_type_id = H5Tcopy(H5T_C_S1); - H5Tset_size(attr_type_id, matvar->isLogical ? 7 : strlen(ClassNames[class_type])); - aspace_id = H5Screate(H5S_SCALAR); - attr_id = - H5Acreate(sparse_id, "MATLAB_class", attr_type_id, aspace_id, H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, attr_type_id, - matvar->isLogical ? "logical" : ClassNames[class_type]) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - H5Tclose(attr_type_id); - - if ( MATIO_E_NO_ERROR == err ) { - if ( matvar->isLogical ) { - /* Write the MATLAB_int_decode attribute */ - int int_decode = 1; - aspace_id = H5Screate(H5S_SCALAR); - attr_id = H5Acreate(sparse_id, "MATLAB_int_decode", H5T_NATIVE_INT, aspace_id, - H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, H5T_NATIVE_INT, &int_decode) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - } - } - - if ( MATIO_E_NO_ERROR == err ) { - sparse_attr_value = matvar->dims[0]; - size_type_id = ClassType2H5T(MAT_C_UINT64); - aspace_id = H5Screate(H5S_SCALAR); - attr_id = H5Acreate(sparse_id, "MATLAB_sparse", size_type_id, aspace_id, H5P_DEFAULT, - H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, size_type_id, &sparse_attr_value) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Sclose(aspace_id); - H5Aclose(attr_id); - } - - if ( MATIO_E_NO_ERROR == err ) { - ndata = sparse->ndata; - h5_type = DataType2H5T(matvar->data_type); - h5_dtype = DataType(h5_type, matvar->isComplex); - mspace_id = H5Screate_simple(1, &ndata, NULL); - dset_id = H5Dcreate(sparse_id, "data", h5_dtype, mspace_id, H5P_DEFAULT, H5P_DEFAULT, - H5P_DEFAULT); - H5Tclose(h5_dtype); - err = Mat_H5WriteData(dset_id, h5_type, H5S_ALL, H5S_ALL, matvar->isComplex, - sparse->data); - H5Dclose(dset_id); - H5Sclose(mspace_id); - } - - if ( MATIO_E_NO_ERROR == err ) { - nir = sparse->nir; - mspace_id = H5Screate_simple(1, &nir, NULL); - dset_id = H5Dcreate(sparse_id, "ir", size_type_id, mspace_id, H5P_DEFAULT, H5P_DEFAULT, - H5P_DEFAULT); - err = Mat_H5WriteData(dset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, 0, sparse->ir); - H5Dclose(dset_id); - H5Sclose(mspace_id); - } - - if ( MATIO_E_NO_ERROR == err ) { - njc = sparse->njc; - mspace_id = H5Screate_simple(1, &njc, NULL); - dset_id = H5Dcreate(sparse_id, "jc", size_type_id, mspace_id, H5P_DEFAULT, H5P_DEFAULT, - H5P_DEFAULT); - err = Mat_H5WriteData(dset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, 0, sparse->jc); - H5Dclose(dset_id); - H5Sclose(mspace_id); - } - H5Gclose(sparse_id); - } - - return err; -} - -/** @if mat_devman - * @brief Writes a structure matlab variable to the specified HDF id with the - * given name - * - * @ingroup mat_internal - * @param id HDF id of the parent object - * @param matvar pointer to the structure variable - * @param name Name of the HDF dataset - * @param refs_id pointer to the id of the /#refs# group in HDF5 - * @param dims array of permuted dimensions - * @param max_dims maximum dimensions - * @retval 0 on success - * @endif - */ -static int -Mat_VarWriteStruct73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, hsize_t *dims, - hsize_t *max_dims) -{ - int err; - hsize_t nelems; - - { - size_t tmp = 1; - err = Mat_MulDims(matvar, &tmp); - nelems = (hsize_t)tmp; - } - - if ( err || 0 == nelems || NULL == matvar->data ) { - err = Mat_VarWriteEmpty(id, matvar, name, ClassNames[matvar->class_type]); - } else { - hid_t struct_id = H5Gcreate(id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - if ( struct_id < 0 ) { - Mat_Critical("Error creating group for struct %s", name); - err = MATIO_E_OUTPUT_BAD_DATA; - } else { - hid_t attr_id, aspace_id; - hid_t str_type_id; - matvar_t **fields = (matvar_t **)matvar->data; - hsize_t nfields = matvar->internal->num_fields, k; - - str_type_id = H5Tcopy(H5T_C_S1); - H5Tset_size(str_type_id, 6); - aspace_id = H5Screate(H5S_SCALAR); - attr_id = H5Acreate(struct_id, "MATLAB_class", str_type_id, aspace_id, H5P_DEFAULT, - H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, str_type_id, "struct") ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Aclose(attr_id); - H5Sclose(aspace_id); - - /* Structure with no fields */ - if ( nfields == 0 ) { - H5Gclose(struct_id); - H5Tclose(str_type_id); - return err; - } - - if ( MATIO_E_NO_ERROR == err ) { - hvl_t *fieldnames = (hvl_t *)malloc((size_t)nfields * sizeof(*fieldnames)); - if ( NULL != fieldnames ) { - hid_t fieldnames_id; - for ( k = 0; k < nfields; k++ ) { - fieldnames[k].len = strlen(matvar->internal->fieldnames[k]); - fieldnames[k].p = matvar->internal->fieldnames[k]; - } - H5Tset_size(str_type_id, 1); - fieldnames_id = H5Tvlen_create(str_type_id); - aspace_id = H5Screate_simple(1, &nfields, NULL); - attr_id = H5Acreate(struct_id, "MATLAB_fields", fieldnames_id, aspace_id, - H5P_DEFAULT, H5P_DEFAULT); - if ( 0 > H5Awrite(attr_id, fieldnames_id, fieldnames) ) - err = MATIO_E_GENERIC_WRITE_ERROR; - H5Aclose(attr_id); - H5Sclose(aspace_id); - H5Tclose(fieldnames_id); - H5Tclose(str_type_id); - free(fieldnames); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - - if ( MATIO_E_NO_ERROR == err ) { - if ( 1 == nelems && NULL == max_dims ) { - for ( k = 0; k < nfields; k++ ) { - if ( NULL != fields[k] ) - fields[k]->compression = matvar->compression; - err = Mat_VarWriteNext73(struct_id, fields[k], - matvar->internal->fieldnames[k], refs_id); - } - } else { - if ( *refs_id < 0 ) { - if ( H5Lexists(id, "/#refs#", H5P_DEFAULT) ) { - *refs_id = H5Gopen(id, "/#refs#", H5P_DEFAULT); - } else { - *refs_id = - H5Gcreate(id, "/#refs#", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - } - } - if ( *refs_id > -1 ) { - hid_t plist = H5P_DEFAULT; - hobj_ref_t **refs = (hobj_ref_t **)calloc((size_t)nfields, sizeof(*refs)); - if ( NULL != refs ) { - hsize_t l; - for ( l = 0; l < nfields; l++ ) { - refs[l] = (hobj_ref_t *)calloc((size_t)nelems, sizeof(*refs[l])); - if ( NULL == refs[l] ) { - err = MATIO_E_OUT_OF_MEMORY; - break; - } - } - - if ( MATIO_E_NO_ERROR == err ) { - for ( k = 0; k < nelems; k++ ) { - for ( l = 0; l < nfields; l++ ) { - err = Mat_VarWriteRef(id, fields[k * nfields + l], - matvar->compression, refs_id, - refs[l] + k); - if ( err ) - break; - } - if ( err ) - break; - } - } - - if ( MATIO_E_NO_ERROR == err ) { - if ( NULL != max_dims ) { - plist = H5Pcreate(H5P_DATASET_CREATE); - if ( MAX_RANK >= matvar->rank ) { - hsize_t chunk_dims[MAX_RANK]; - Mat_H5GetChunkSize(matvar->rank, dims, chunk_dims); - H5Pset_chunk(plist, matvar->rank, chunk_dims); - } else { - hsize_t *chunk_dims = - (hsize_t *)malloc(matvar->rank * sizeof(hsize_t)); - if ( NULL != chunk_dims ) { - Mat_H5GetChunkSize(matvar->rank, dims, chunk_dims); - H5Pset_chunk(plist, matvar->rank, chunk_dims); - free(chunk_dims); - } else { - H5Pclose(plist); - plist = H5P_DEFAULT; - err = MATIO_E_OUT_OF_MEMORY; - } - } - } else { - plist = H5P_DEFAULT; - } - } - - if ( MATIO_E_NO_ERROR == err ) { - hid_t mspace_id = H5Screate_simple(matvar->rank, dims, max_dims); - for ( l = 0; l < nfields; l++ ) { - hid_t dset_id = H5Dcreate( - struct_id, matvar->internal->fieldnames[l], H5T_STD_REF_OBJ, - mspace_id, H5P_DEFAULT, plist, H5P_DEFAULT); - err = Mat_H5WriteData(dset_id, H5T_STD_REF_OBJ, H5S_ALL, - H5S_ALL, 0, refs[l]); - H5Dclose(dset_id); - if ( err ) - break; - } - H5Sclose(mspace_id); - } - for ( l = 0; l < nfields; l++ ) - free(refs[l]); - free(refs); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - if ( H5P_DEFAULT != plist ) - H5Pclose(plist); - } else { - err = MATIO_E_OUTPUT_BAD_DATA; - } - } - } - H5Gclose(struct_id); - } - } - - return err; -} - -static int -Mat_VarWriteAppendStruct73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, - hsize_t *dims, int dim) -{ - int err = MATIO_E_NO_ERROR; - hsize_t nelems = 1; - - { - int k; - for ( k = 0; k < matvar->rank; k++ ) { - nelems *= dims[k]; - } - } - - if ( 0 != nelems && NULL != matvar->data ) { - if ( H5Lexists(id, name, H5P_DEFAULT) ) { - hobj_ref_t **refs; - hsize_t nfields = matvar->internal->num_fields; - matvar_t **fields = (matvar_t **)matvar->data; - - if ( *refs_id <= -1 ) - return MATIO_E_OUTPUT_BAD_DATA; - - refs = (hobj_ref_t **)calloc((size_t)nfields, sizeof(*refs)); - if ( NULL != refs ) { - hsize_t l; - for ( l = 0; l < nfields; l++ ) { - refs[l] = (hobj_ref_t *)calloc((size_t)nelems, sizeof(*refs[l])); - if ( NULL == refs[l] ) { - err = MATIO_E_OUT_OF_MEMORY; - break; - } - } - - if ( MATIO_E_NO_ERROR == err ) { - hsize_t k; - for ( k = 0; k < nelems; k++ ) { - for ( l = 0; l < nfields; l++ ) { - err = Mat_VarWriteRef(id, fields[k * nfields + l], matvar->compression, - refs_id, refs[l] + k); - if ( err ) - break; - } - if ( err ) - break; - } - } - - if ( MATIO_E_NO_ERROR == err ) { - hid_t struct_id = H5Gopen(id, name, H5P_DEFAULT); - for ( l = 0; l < nfields; l++ ) { - err = Mat_H5WriteAppendData(struct_id, H5T_STD_REF_OBJ, matvar->rank, - matvar->internal->fieldnames[l], matvar->dims, - dims, dim, 0, refs[l]); - if ( err ) - break; - } - H5Gclose(struct_id); - } - for ( l = 0; l < nfields; l++ ) - free(refs[l]); - free(refs); - } - } else { - /* Create with unlimited number of dimensions */ - if ( MAX_RANK >= matvar->rank ) { - hsize_t max_dims[MAX_RANK]; - int k; - for ( k = 0; k < matvar->rank; k++ ) { - max_dims[k] = H5S_UNLIMITED; - } - err = Mat_VarWriteStruct73(id, matvar, name, refs_id, dims, max_dims); - } else { - hsize_t *max_dims = (hsize_t *)malloc(matvar->rank * sizeof(hsize_t)); - if ( NULL != max_dims ) { - int k; - for ( k = 0; k < matvar->rank; k++ ) { - max_dims[k] = H5S_UNLIMITED; - } - err = Mat_VarWriteStruct73(id, matvar, name, refs_id, dims, max_dims); - free(max_dims); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - } - } - - return err; -} - -static int -Mat_VarWriteNext73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id) -{ - int err; - - if ( NULL == matvar ) { - size_t dims[2] = {0, 0}; - return Mat_WriteEmptyVariable73(id, name, 2, dims); - } - - if ( MAX_RANK >= matvar->rank ) { - hsize_t perm_dims[MAX_RANK]; - err = Mat_VarWriteNextType73(id, matvar, name, refs_id, perm_dims); - } else { - hsize_t *perm_dims = (hsize_t *)malloc(matvar->rank * sizeof(hsize_t)); - if ( NULL != perm_dims ) { - err = Mat_VarWriteNextType73(id, matvar, name, refs_id, perm_dims); - free(perm_dims); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - - return err; -} - -static int -Mat_VarWriteAppendNext73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, int dim) -{ - int err; - - if ( MAX_RANK >= matvar->rank ) { - hsize_t perm_dims[MAX_RANK]; - err = Mat_VarWriteAppendNextType73(id, matvar, name, refs_id, perm_dims, dim); - } else { - hsize_t *perm_dims = (hsize_t *)malloc(matvar->rank * sizeof(hsize_t)); - if ( NULL != perm_dims ) { - err = Mat_VarWriteAppendNextType73(id, matvar, name, refs_id, perm_dims, dim); - free(perm_dims); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - - return err; -} - -static int -Mat_VarWriteNextType73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, hsize_t *dims) -{ - int err, k; - - /* Permute dimensions */ - for ( k = 0; k < matvar->rank; k++ ) { - dims[k] = matvar->dims[matvar->rank - k - 1]; - } - - if ( matvar->isLogical && matvar->class_type != MAT_C_SPARSE ) { - err = Mat_VarWriteLogical73(id, matvar, name, dims); - } else { - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: - err = Mat_VarWriteNumeric73(id, matvar, name, dims, NULL); - break; - case MAT_C_CHAR: - err = Mat_VarWriteChar73(id, matvar, name, dims); - break; - case MAT_C_STRUCT: - err = Mat_VarWriteStruct73(id, matvar, name, refs_id, dims, NULL); - break; - case MAT_C_CELL: - err = Mat_VarWriteCell73(id, matvar, name, refs_id, dims); - break; - case MAT_C_SPARSE: - err = Mat_VarWriteSparse73(id, matvar, name); - break; - case MAT_C_EMPTY: - err = Mat_WriteEmptyVariable73(id, name, matvar->rank, matvar->dims); - break; - case MAT_C_FUNCTION: - case MAT_C_OBJECT: - case MAT_C_OPAQUE: - err = MATIO_E_OPERATION_NOT_SUPPORTED; - break; - default: - err = MATIO_E_OUTPUT_BAD_DATA; - break; - } - } - - return err; -} - -static int -Mat_VarWriteAppendNextType73(hid_t id, matvar_t *matvar, const char *name, hid_t *refs_id, - hsize_t *dims, int dim) -{ - int err, k; - - /* Permute dimensions */ - for ( k = 0; k < matvar->rank; k++ ) { - dims[k] = matvar->dims[matvar->rank - k - 1]; - } - - if ( !matvar->isLogical ) { - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: - err = Mat_VarWriteAppendNumeric73(id, matvar, name, dims, dim); - break; - case MAT_C_STRUCT: - err = Mat_VarWriteAppendStruct73(id, matvar, name, refs_id, dims, dim); - break; - case MAT_C_EMPTY: - case MAT_C_CHAR: - case MAT_C_CELL: - case MAT_C_SPARSE: - case MAT_C_FUNCTION: - case MAT_C_OBJECT: - case MAT_C_OPAQUE: - err = Mat_VarWriteNextType73(id, matvar, name, refs_id, dims); - break; - default: - err = MATIO_E_OUTPUT_BAD_DATA; - break; - } - } else { - err = MATIO_E_OPERATION_NOT_SUPPORTED; - } - - return err; -} - -/** @if mat_devman - * @brief Creates a new Matlab MAT version 7.3 file - * - * Tries to create a new Matlab MAT file with the given name and optional - * header string. If no header string is given, the default string - * is used containing the software, version, and date in it. If a header - * string is given, at most the first 116 characters is written to the file. - * The given header string need not be the full 116 characters, but MUST be - * NULL terminated. - * @ingroup mat_internal - * @param matname Name of MAT file to create - * @param hdr_str Optional header string, NULL to use default - * @return A pointer to the MAT file or NULL if it failed. This is not a - * simple FILE * and should not be used as one. - * @endif - */ -static mat_t * -Mat_Create73(const char *matname, const char *hdr_str) -{ - FILE *fp = NULL; - mat_int16_t endian = 0, version; - mat_t *mat = NULL; - size_t err; - time_t t; - hid_t plist_id, fid, plist_ap; - - plist_id = H5Pcreate(H5P_FILE_CREATE); - H5Pset_userblock(plist_id, 512); - plist_ap = H5Pcreate(H5P_FILE_ACCESS); -#if H5_VERSION_GE(1, 10, 2) - H5Pset_libver_bounds(plist_ap, H5F_LIBVER_EARLIEST, H5F_LIBVER_V18); -#endif - fid = H5Fcreate(matname, H5F_ACC_TRUNC, plist_id, plist_ap); - H5Fclose(fid); - H5Pclose(plist_id); - -#if defined(_WIN32) && defined(_MSC_VER) && H5_VERSION_GE(1, 11, 6) - { - wchar_t *wname = utf82u(matname); - if ( NULL != wname ) { - fp = _wfopen(wname, L"r+b"); - free(wname); - } - } -#else - fp = fopen(matname, "r+b"); -#endif - if ( !fp ) { - H5Pclose(plist_ap); - return NULL; - } - - (void)fseek(fp, 0, SEEK_SET); - - mat = (mat_t *)malloc(sizeof(*mat)); - if ( mat == NULL ) { - fclose(fp); - H5Pclose(plist_ap); - return NULL; - } - - mat->fp = NULL; - mat->header = NULL; - mat->subsys_offset = NULL; - mat->filename = NULL; - mat->version = 0; - mat->byteswap = 0; - mat->mode = 0; - mat->bof = 128; - mat->next_index = 0; - mat->num_datasets = 0; - mat->refs_id = -1; - mat->dir = NULL; - - t = time(NULL); - mat->filename = Mat_strdup(matname); - mat->mode = MAT_ACC_RDWR; - mat->byteswap = 0; - mat->header = (char *)malloc(128 * sizeof(char)); - mat->subsys_offset = (char *)malloc(8 * sizeof(char)); - memset(mat->header, ' ', 128); - if ( hdr_str == NULL ) { - err = mat_snprintf(mat->header, 116, - "MATLAB 7.3 MAT-file, Platform: %s, " - "Created by: libmatio v%d.%d.%d on %s HDF5 schema 0.5", - MATIO_PLATFORM, MATIO_MAJOR_VERSION, MATIO_MINOR_VERSION, - MATIO_RELEASE_LEVEL, ctime(&t)); - } else { - err = mat_snprintf(mat->header, 116, "%s", hdr_str); - } - if ( err >= 116 ) - mat->header[115] = '\0'; /* Just to make sure it's NULL terminated */ - memset(mat->subsys_offset, ' ', 8); - mat->version = (int)0x0200; - endian = 0x4d49; - - version = 0x0200; - - fwrite(mat->header, 1, 116, fp); - fwrite(mat->subsys_offset, 1, 8, fp); - fwrite(&version, 2, 1, fp); - fwrite(&endian, 2, 1, fp); - - fclose(fp); - - fid = H5Fopen(matname, H5F_ACC_RDWR, plist_ap); - H5Pclose(plist_ap); - - mat->fp = malloc(sizeof(hid_t)); - *(hid_t *)mat->fp = fid; - - return mat; -} - -/** @if mat_devman - * @brief Closes a MAT file - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @retval 0 on success - * @endif - */ -static int -Mat_Close73(mat_t *mat) -{ - int err = MATIO_E_NO_ERROR; - if ( mat->refs_id > -1 ) - H5Gclose(mat->refs_id); - if ( 0 > H5Fclose(*(hid_t *)mat->fp) ) - err = MATIO_E_FILESYSTEM_ERROR_ON_CLOSE; - free(mat->fp); - mat->fp = NULL; - return err; -} - -/** @if mat_devman - * @brief Reads the MAT variable identified by matvar - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar MAT variable pointer - * @retval 0 on success - * @endif - */ -static int -Mat_VarRead73(mat_t *mat, matvar_t *matvar) -{ - int err = MATIO_E_NO_ERROR; - hid_t fid, dset_id, ref_id; - - if ( NULL == mat || NULL == matvar ) - return MATIO_E_BAD_ARGUMENT; - else if ( NULL == matvar->internal->hdf5_name && 0 > matvar->internal->id ) - return MATIO_E_READ_VARIABLE_DOES_NOT_EXIST; - - fid = *(hid_t *)mat->fp; - - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: { - size_t nelems = 1; - matvar->data_size = (int)Mat_SizeOfClass(matvar->class_type); - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - err = Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - if ( nelems < 1 ) - break; - - if ( NULL != matvar->internal->hdf5_name ) { - ref_id = H5Dopen(fid, matvar->internal->hdf5_name, H5P_DEFAULT); - } else { - ref_id = matvar->internal->id; - H5Iinc_ref(ref_id); - } - if ( 0 < matvar->internal->hdf5_ref ) { - dset_id = H5RDEREFERENCE(ref_id, H5R_OBJECT, &matvar->internal->hdf5_ref); - } else { - dset_id = ref_id; - H5Iinc_ref(dset_id); - } - - if ( !matvar->isComplex ) { - matvar->data = malloc(matvar->nbytes); - } else { - matvar->data = ComplexMalloc(matvar->nbytes); - } - if ( NULL != matvar->data ) { - err = Mat_H5ReadData(dset_id, ClassType2H5T(matvar->class_type), H5S_ALL, H5S_ALL, - matvar->isComplex, matvar->data); - } - H5Dclose(dset_id); - H5Dclose(ref_id); - break; - } - case MAT_C_CHAR: { - size_t nelems = 1; - matvar->data_size = (int)Mat_SizeOf(matvar->data_type); - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - err = Mul(&matvar->nbytes, nelems, matvar->data_size); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - if ( NULL != matvar->internal->hdf5_name ) { - dset_id = H5Dopen(fid, matvar->internal->hdf5_name, H5P_DEFAULT); - } else { - dset_id = matvar->internal->id; - H5Iinc_ref(dset_id); - } - if ( matvar->nbytes > 0 ) { - matvar->data = malloc(matvar->nbytes); - if ( NULL != matvar->data ) { - herr_t herr = H5Dread(dset_id, DataType2H5T(matvar->data_type), H5S_ALL, - H5S_ALL, H5P_DEFAULT, matvar->data); - if ( herr < 0 ) { - err = MATIO_E_GENERIC_READ_ERROR; - } - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - H5Dclose(dset_id); - break; - } - case MAT_C_STRUCT: { - matvar_t **fields; - size_t i, nelems_x_nfields, nelems = 1; - - if ( !matvar->internal->num_fields || NULL == matvar->data ) - break; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - err = Mul(&nelems_x_nfields, nelems, matvar->internal->num_fields); - if ( err ) { - Mat_Critical("Integer multiplication overflow"); - return err; - } - - fields = (matvar_t **)matvar->data; - for ( i = 0; i < nelems_x_nfields; i++ ) { - if ( NULL != fields[i] && 0 < fields[i]->internal->hdf5_ref && - -1 < fields[i]->internal->id ) { - /* Dataset of references */ - err = Mat_H5ReadNextReferenceData(fields[i]->internal->id, fields[i], mat); - } else { - err = Mat_VarRead73(mat, fields[i]); - } - if ( err ) { - break; - } - } - break; - } - case MAT_C_CELL: { - matvar_t **cells; - size_t i, nelems; - - if ( NULL == matvar->data ) { - Mat_Critical("Data is NULL for cell array %s", matvar->name); - err = MATIO_E_FILE_FORMAT_VIOLATION; - break; - } - nelems = matvar->nbytes / matvar->data_size; - cells = (matvar_t **)matvar->data; - for ( i = 0; i < nelems; i++ ) { - if ( NULL != cells[i] ) { - err = Mat_H5ReadNextReferenceData(cells[i]->internal->id, cells[i], mat); - } - if ( err ) { - break; - } - } - break; - } - case MAT_C_SPARSE: { - hid_t sparse_dset_id; - mat_sparse_t *sparse_data = (mat_sparse_t *)calloc(1, sizeof(*sparse_data)); - - if ( NULL != matvar->internal->hdf5_name ) { - dset_id = H5Gopen(fid, matvar->internal->hdf5_name, H5P_DEFAULT); - } else { - dset_id = matvar->internal->id; - H5Iinc_ref(dset_id); - } - - if ( H5Lexists(dset_id, "ir", H5P_DEFAULT) ) { - size_t *dims; - hsize_t nelems; - int rank; - - sparse_dset_id = H5Dopen(dset_id, "ir", H5P_DEFAULT); - dims = Mat_H5ReadDims(sparse_dset_id, &nelems, &rank); - if ( NULL != dims ) { - size_t nbytes; - sparse_data->nir = (mat_uint32_t)dims[0]; - free(dims); - err = Mul(&nbytes, sparse_data->nir, sizeof(mat_uint32_t)); - if ( err ) { - H5Dclose(sparse_dset_id); - H5Gclose(dset_id); - free(sparse_data); - Mat_Critical("Integer multiplication overflow"); - return err; - } - sparse_data->ir = (mat_uint32_t *)malloc(nbytes); - if ( sparse_data->ir != NULL ) { - herr_t herr = H5Dread(sparse_dset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, - H5P_DEFAULT, sparse_data->ir); - if ( herr < 0 ) { - err = MATIO_E_GENERIC_READ_ERROR; - } - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } else { - err = MATIO_E_UNKNOWN_ERROR; - } - H5Dclose(sparse_dset_id); - if ( err ) { - H5Gclose(dset_id); - free(sparse_data); - return err; - } - } - - if ( H5Lexists(dset_id, "jc", H5P_DEFAULT) ) { - size_t *dims; - hsize_t nelems; - int rank; - - sparse_dset_id = H5Dopen(dset_id, "jc", H5P_DEFAULT); - dims = Mat_H5ReadDims(sparse_dset_id, &nelems, &rank); - if ( NULL != dims ) { - size_t nbytes; - sparse_data->njc = (mat_uint32_t)dims[0]; - free(dims); - err = Mul(&nbytes, sparse_data->njc, sizeof(mat_uint32_t)); - if ( err ) { - H5Dclose(sparse_dset_id); - H5Gclose(dset_id); - free(sparse_data); - Mat_Critical("Integer multiplication overflow"); - return err; - } - sparse_data->jc = (mat_uint32_t *)malloc(nbytes); - if ( sparse_data->jc != NULL ) { - herr_t herr = H5Dread(sparse_dset_id, H5T_NATIVE_UINT, H5S_ALL, H5S_ALL, - H5P_DEFAULT, sparse_data->jc); - if ( herr < 0 ) { - err = MATIO_E_GENERIC_READ_ERROR; - } - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } else { - err = MATIO_E_UNKNOWN_ERROR; - } - H5Dclose(sparse_dset_id); - if ( err ) { - H5Gclose(dset_id); - free(sparse_data); - return err; - } - } - - if ( H5Lexists(dset_id, "data", H5P_DEFAULT) ) { - size_t *dims; - hsize_t nelems; - int rank; - - sparse_dset_id = H5Dopen(dset_id, "data", H5P_DEFAULT); - dims = Mat_H5ReadDims(sparse_dset_id, &nelems, &rank); - if ( NULL != dims ) { - size_t ndata_bytes; - sparse_data->nzmax = (mat_uint32_t)dims[0]; - sparse_data->ndata = (mat_uint32_t)dims[0]; - free(dims); - err = Mul(&ndata_bytes, sparse_data->nzmax, Mat_SizeOf(matvar->data_type)); - if ( err ) { - H5Dclose(sparse_dset_id); - H5Gclose(dset_id); - free(sparse_data); - Mat_Critical("Integer multiplication overflow"); - return err; - } - matvar->data_size = sizeof(mat_sparse_t); - matvar->nbytes = matvar->data_size; - if ( !matvar->isComplex ) { - sparse_data->data = malloc(ndata_bytes); - } else { - sparse_data->data = ComplexMalloc(ndata_bytes); - } - if ( NULL != sparse_data->data ) { - err = - Mat_H5ReadData(sparse_dset_id, DataType2H5T(matvar->data_type), H5S_ALL, - H5S_ALL, matvar->isComplex, sparse_data->data); - } else { - err = MATIO_E_OUT_OF_MEMORY; - } - } - H5Dclose(sparse_dset_id); - } - H5Gclose(dset_id); - matvar->data = sparse_data; - break; - } - case MAT_C_EMPTY: - case MAT_C_FUNCTION: - case MAT_C_OBJECT: - case MAT_C_OPAQUE: - break; - default: - err = MATIO_E_FAIL_TO_IDENTIFY; - break; - } - return err; -} - -/** @if mat_devman - * @brief Reads a slab of data from the mat variable @c matvar - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @param data pointer to store the read data in (must be of size - * edge[0]*...edge[rank-1]*Mat_SizeOfClass(matvar->class_type)) - * @param start index to start reading data in each dimension - * @param stride write data every @c stride elements in each dimension - * @param edge number of elements to read in each dimension - * @retval 0 on success - * @endif - */ -static int -Mat_VarReadData73(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, int *edge) -{ - int err = MATIO_E_NO_ERROR, k; - hid_t fid, dset_id, ref_id, dset_space, mem_space; - hsize_t *dset_start_stride_edge; - hsize_t *dset_start, *dset_stride, *dset_edge; - - if ( NULL == mat || NULL == matvar || NULL == data || NULL == start || NULL == stride || - NULL == edge ) - return MATIO_E_BAD_ARGUMENT; - else if ( NULL == matvar->internal->hdf5_name && 0 > matvar->internal->id ) - return MATIO_E_FAIL_TO_IDENTIFY; - - fid = *(hid_t *)mat->fp; - - dset_start_stride_edge = (hsize_t *)malloc(matvar->rank * 3 * sizeof(hsize_t)); - if ( NULL == dset_start_stride_edge ) { - return MATIO_E_OUT_OF_MEMORY; - } - dset_start = &dset_start_stride_edge[0]; - dset_stride = &dset_start_stride_edge[matvar->rank]; - dset_edge = &dset_start_stride_edge[2 * matvar->rank]; - - for ( k = 0; k < matvar->rank; k++ ) { - dset_start[k] = start[matvar->rank - k - 1]; - dset_stride[k] = stride[matvar->rank - k - 1]; - dset_edge[k] = edge[matvar->rank - k - 1]; - } - mem_space = H5Screate_simple(matvar->rank, dset_edge, NULL); - - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: - if ( NULL != matvar->internal->hdf5_name ) { - ref_id = H5Dopen(fid, matvar->internal->hdf5_name, H5P_DEFAULT); - } else { - ref_id = matvar->internal->id; - H5Iinc_ref(ref_id); - } - if ( 0 < matvar->internal->hdf5_ref ) { - dset_id = H5RDEREFERENCE(ref_id, H5R_OBJECT, &matvar->internal->hdf5_ref); - } else { - dset_id = ref_id; - H5Iinc_ref(dset_id); - } - - dset_space = H5Dget_space(dset_id); - H5Sselect_hyperslab(dset_space, H5S_SELECT_SET, dset_start, dset_stride, dset_edge, - NULL); - err = Mat_H5ReadData(dset_id, ClassType2H5T(matvar->class_type), mem_space, dset_space, - matvar->isComplex, data); - H5Sclose(dset_space); - H5Dclose(dset_id); - H5Dclose(ref_id); - break; - default: - err = MATIO_E_FAIL_TO_IDENTIFY; - break; - } - H5Sclose(mem_space); - free(dset_start_stride_edge); - - return err; -} - -/** @if mat_devman - * @brief Reads a subset of a MAT variable using a 1-D indexing - * - * Reads data from a MAT variable using a linear (1-D) indexing mode. The - * variable must have been read by Mat_VarReadInfo. - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @param data pointer to store the read data in (must be of size - * edge*Mat_SizeOfClass(matvar->class_type)) - * @param start starting index - * @param stride stride of data - * @param edge number of elements to read - * @retval 0 on success - * @endif - */ -static int -Mat_VarReadDataLinear73(mat_t *mat, matvar_t *matvar, void *data, int start, int stride, int edge) -{ - int err = MATIO_E_NO_ERROR, k; - hid_t fid, dset_id, dset_space, mem_space; - hsize_t *points, dset_edge, *dimp; - - if ( NULL == mat || NULL == matvar || NULL == data ) - return MATIO_E_BAD_ARGUMENT; - else if ( NULL == matvar->internal->hdf5_name && 0 > matvar->internal->id ) - return MATIO_E_FAIL_TO_IDENTIFY; - - fid = *(hid_t *)mat->fp; - - dset_edge = edge; - mem_space = H5Screate_simple(1, &dset_edge, NULL); - - switch ( matvar->class_type ) { - case MAT_C_DOUBLE: - case MAT_C_SINGLE: - case MAT_C_INT64: - case MAT_C_UINT64: - case MAT_C_INT32: - case MAT_C_UINT32: - case MAT_C_INT16: - case MAT_C_UINT16: - case MAT_C_INT8: - case MAT_C_UINT8: - points = (hsize_t *)malloc(matvar->rank * (size_t)dset_edge * sizeof(*points)); - if ( NULL == points ) { - err = MATIO_E_OUT_OF_MEMORY; - break; - } - dimp = (hsize_t *)malloc(matvar->rank * sizeof(hsize_t)); - if ( NULL == dimp ) { - err = MATIO_E_OUT_OF_MEMORY; - free(points); - break; - } - dimp[0] = 1; - for ( k = 1; k < matvar->rank; k++ ) - dimp[k] = dimp[k - 1] * matvar->dims[k - 1]; - for ( k = 0; k < edge; k++ ) { - size_t l, coord; - coord = (size_t)(start + k * stride); - for ( l = matvar->rank; l--; ) { - size_t idx = (size_t)(coord / dimp[l]); - points[matvar->rank * (k + 1) - 1 - l] = idx; - coord -= idx * (size_t)dimp[l]; - } - } - free(dimp); - - if ( NULL != matvar->internal->hdf5_name ) { - dset_id = H5Dopen(fid, matvar->internal->hdf5_name, H5P_DEFAULT); - } else { - dset_id = matvar->internal->id; - H5Iinc_ref(dset_id); - } - dset_space = H5Dget_space(dset_id); - H5Sselect_elements(dset_space, H5S_SELECT_SET, (size_t)dset_edge, points); - free(points); - err = Mat_H5ReadData(dset_id, ClassType2H5T(matvar->class_type), mem_space, dset_space, - matvar->isComplex, data); - H5Sclose(dset_space); - H5Dclose(dset_id); - break; - default: - err = MATIO_E_FAIL_TO_IDENTIFY; - break; - } - H5Sclose(mem_space); - - return err; -} - -/** @if mat_devman - * @brief Reads the header information for the next MAT variable - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @return pointer to the MAT variable or NULL - * @endif - */ -static matvar_t * -Mat_VarReadNextInfo73(mat_t *mat) -{ - hid_t id; - hsize_t idx; - herr_t herr; - struct ReadNextIterData mat_data; - - if ( mat == NULL ) - return NULL; - - if ( mat->next_index >= mat->num_datasets ) - return NULL; - - id = *(hid_t *)mat->fp; - idx = (hsize_t)mat->next_index; - mat_data.mat = mat; - mat_data.matvar = NULL; - herr = H5Literate(id, H5_INDEX_NAME, H5_ITER_NATIVE, &idx, Mat_VarReadNextInfoIterate, - (void *)&mat_data); - if ( herr > 0 ) - mat->next_index = (size_t)idx; - return mat_data.matvar; -} - -static herr_t -Mat_VarReadNextInfoIterate(hid_t id, const char *name, const H5L_info_t *info, void *op_data) -{ - mat_t *mat; - H5O_INFO_T object_info; - struct ReadNextIterData *mat_data; - - /* FIXME: follow symlinks, datatypes? */ - - /* Check that this is not the /#refs# or /"#subsystem#" group */ - if ( 0 == strcmp(name, "#refs#") || 0 == strcmp(name, "#subsystem#") ) - return 0; - - object_info.type = H5O_TYPE_UNKNOWN; - H5OGET_INFO_BY_NAME(id, name, &object_info, H5P_DEFAULT); - if ( H5O_TYPE_DATASET != object_info.type && H5O_TYPE_GROUP != object_info.type ) - return 0; - - mat_data = (struct ReadNextIterData *)op_data; - if ( NULL == mat_data ) - return -1; - mat = mat_data->mat; - - switch ( object_info.type ) { - case H5O_TYPE_DATASET: { - int err; - hid_t dset_id; - matvar_t *matvar = Mat_VarCalloc(); - if ( NULL == matvar ) - return -1; - - matvar->name = Mat_strdup(name); - if ( NULL == matvar->name ) { - Mat_VarFree(matvar); - return -1; - } - - dset_id = H5Dopen(id, name, H5P_DEFAULT); - err = Mat_H5ReadDatasetInfo(mat, matvar, dset_id); - if ( matvar->internal->id != dset_id ) { - /* Close dataset and increment count */ - H5Dclose(dset_id); - } - if ( err ) { - Mat_VarFree(matvar); - return -1; - } - mat_data->matvar = matvar; - break; - } - case H5O_TYPE_GROUP: { - int err; - hid_t dset_id; - matvar_t *matvar = Mat_VarCalloc(); - if ( NULL == matvar ) - return -1; - - matvar->name = Mat_strdup(name); - if ( NULL == matvar->name ) { - Mat_VarFree(matvar); - return -1; - } - - dset_id = H5Gopen(id, name, H5P_DEFAULT); - err = Mat_H5ReadGroupInfo(mat, matvar, dset_id); - H5Gclose(dset_id); - if ( err ) { - Mat_VarFree(matvar); - return -1; - } - mat_data->matvar = matvar; - break; - } - default: - break; - } - - return 1; -} - -/** @if mat_devman - * @brief Writes a matlab variable to a version 7.3 matlab file - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @param compress option to compress the variable - * (only works for numeric types) - * @retval 0 on success - * @endif - */ -static int -Mat_VarWrite73(mat_t *mat, matvar_t *matvar, int compress) -{ - hid_t id; - - if ( NULL == mat || NULL == matvar ) - return MATIO_E_BAD_ARGUMENT; - - matvar->compression = (enum matio_compression)compress; - - id = *(hid_t *)mat->fp; - return Mat_VarWriteNext73(id, matvar, matvar->name, &(mat->refs_id)); -} - -/** @if mat_devman - * @brief Writes/appends a matlab variable to a version 7.3 matlab file - * - * @ingroup mat_internal - * @param mat MAT file pointer - * @param matvar pointer to the mat variable - * @param compress option to compress the variable - * (only works for numeric types) - * @param dim dimension to append data - * (only works for numeric types) - * @retval 0 on success - * @endif - */ -static int -Mat_VarWriteAppend73(mat_t *mat, matvar_t *matvar, int compress, int dim) -{ - hid_t id; - - if ( NULL == mat || NULL == matvar ) - return MATIO_E_BAD_ARGUMENT; - - matvar->compression = (enum matio_compression)compress; - - id = *(hid_t *)mat->fp; - return Mat_VarWriteAppendNext73(id, matvar, matvar->name, &(mat->refs_id), dim); -} - -#endif - -/* ------------------------------- - * ---------- matvar_cell.c - * ------------------------------- - */ - -/** @brief Returns a pointer to the Cell array at a specific index - * - * Returns a pointer to the Cell Array Field at the given 1-relative index. - * MAT file must be a version 5 matlab file. - * @ingroup MAT - * @param matvar Pointer to the Cell Array MAT variable - * @param index linear index of cell to return - * @return Pointer to the Cell Array Field on success, NULL on error - */ -matvar_t * -Mat_VarGetCell(matvar_t *matvar, int index) -{ - size_t nelems = 1; - matvar_t *cell = NULL; - int err; - - if ( matvar == NULL ) - return NULL; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) - return NULL; - - if ( 0 <= index && (size_t)index < nelems ) - cell = *((matvar_t **)matvar->data + index); - - return cell; -} - -/** @brief Indexes a cell array - * - * Finds cells of a cell array given a start, stride, and edge for each. - * dimension. The cells are placed in a pointer array. The cells should not - * be freed, but the array of pointers should be. If copies are needed, - * use Mat_VarDuplicate on each cell. - * - * Note that this function is limited to structure arrays with a rank less than - * 10. - * - * @ingroup MAT - * @param matvar Cell Array matlab variable - * @param start vector of length rank with 0-relative starting coordinates for - * each dimension. - * @param stride vector of length rank with strides for each dimension. - * @param edge vector of length rank with the number of elements to read in - * each dimension. - * @returns an array of pointers to the cells - */ -matvar_t ** -Mat_VarGetCells(matvar_t *matvar, int *start, int *stride, int *edge) -{ - int i, j, N, I; - size_t idx[10] = - { - 0, - }, - cnt[10] = - { - 0, - }, - dimp[10] = { - 0, - }; - matvar_t **cells; - - if ( matvar == NULL || start == NULL || stride == NULL || edge == NULL ) { - return NULL; - } else if ( matvar->rank > 9 ) { - return NULL; - } - - dimp[0] = matvar->dims[0]; - N = edge[0]; - I = start[0]; - idx[0] = start[0]; - for ( i = 1; i < matvar->rank; i++ ) { - idx[i] = start[i]; - dimp[i] = dimp[i - 1] * matvar->dims[i]; - N *= edge[i]; - I += start[i] * dimp[i - 1]; - } - cells = (matvar_t **)malloc(N * sizeof(matvar_t *)); - for ( i = 0; i < N; i += edge[0] ) { - for ( j = 0; j < edge[0]; j++ ) { - cells[i + j] = *((matvar_t **)matvar->data + I); - I += stride[0]; - } - idx[0] = start[0]; - I = idx[0]; - cnt[1]++; - idx[1] += stride[1]; - for ( j = 1; j < matvar->rank; j++ ) { - if ( cnt[j] == (size_t)edge[j] ) { - cnt[j] = 0; - idx[j] = start[j]; - if ( j < matvar->rank - 1 ) { - cnt[j + 1]++; - idx[j + 1] += stride[j + 1]; - } - } - I += idx[j] * dimp[j - 1]; - } - } - return cells; -} - -/** @brief Indexes a cell array - * - * Finds cells of a cell array given a linear indexed start, stride, and edge. - * The cells are placed in a pointer array. The cells themself should not - * be freed as they are part of the original cell array, but the pointer array - * should be. If copies are needed, use Mat_VarDuplicate on each of the cells. - * MAT file version must be 5. - * @ingroup MAT - * @param matvar Cell Array matlab variable - * @param start starting index - * @param stride stride - * @param edge Number of cells to get - * @returns an array of pointers to the cells - */ -matvar_t ** -Mat_VarGetCellsLinear(matvar_t *matvar, int start, int stride, int edge) -{ - matvar_t **cells = NULL; - - if ( matvar != NULL ) { - int i, I; - cells = (matvar_t **)malloc(edge * sizeof(matvar_t *)); - I = start; - for ( i = 0; i < edge; i++ ) { - cells[i] = *((matvar_t **)matvar->data + I); - I += stride; - } - } - return cells; -} - -/** @brief Sets the element of the cell array at the specific index - * - * Sets the element of the cell array at the given 0-relative index to @c cell. - * @ingroup MAT - * @param matvar Pointer to the cell array variable - * @param index 0-relative linear index of the cell to set - * @param cell Pointer to the cell to set - * @return Pointer to the previous cell element, or NULL if there was no -* previous cell element or error. - */ -matvar_t * -Mat_VarSetCell(matvar_t *matvar, int index, matvar_t *cell) -{ - size_t nelems = 1; - matvar_t **cells, *old_cell = NULL; - int err; - - if ( matvar == NULL || matvar->rank < 1 ) - return NULL; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) - return NULL; - - cells = (matvar_t **)matvar->data; - if ( 0 <= index && (size_t)index < nelems ) { - old_cell = cells[index]; - cells[index] = cell; - } - - return old_cell; -} - -/* ------------------------------- - * ---------- matvar_struct.c - * ------------------------------- - */ - -/** @brief Creates a structure MATLAB variable with the given name and fields - * - * @ingroup MAT - * @param name Name of the structure variable to create - * @param rank Rank of the variable - * @param dims array of dimensions of the variable of size rank - * @param fields Array of @c nfields fieldnames - * @param nfields Number of fields in the structure - * @return Pointer to the new structure MATLAB variable on success, NULL on error - */ -matvar_t * -Mat_VarCreateStruct(const char *name, int rank, size_t *dims, const char **fields, unsigned nfields) -{ - size_t nelems = 1; - int j; - matvar_t *matvar; - - if ( NULL == dims ) - return NULL; - - matvar = Mat_VarCalloc(); - if ( NULL == matvar ) - return NULL; - - matvar->compression = MAT_COMPRESSION_NONE; - if ( NULL != name ) - matvar->name = Mat_strdup(name); - matvar->rank = rank; - matvar->dims = (size_t *)malloc(matvar->rank * sizeof(*matvar->dims)); - for ( j = 0; j < matvar->rank; j++ ) { - matvar->dims[j] = dims[j]; - nelems *= dims[j]; - } - matvar->class_type = MAT_C_STRUCT; - matvar->data_type = MAT_T_STRUCT; - - matvar->data_size = sizeof(matvar_t *); - - if ( nfields ) { - matvar->internal->num_fields = nfields; - matvar->internal->fieldnames = - (char **)malloc(nfields * sizeof(*matvar->internal->fieldnames)); - if ( NULL == matvar->internal->fieldnames ) { - Mat_VarFree(matvar); - matvar = NULL; - } else { - size_t i; - for ( i = 0; i < nfields; i++ ) { - if ( NULL == fields[i] ) { - Mat_VarFree(matvar); - matvar = NULL; - break; - } else { - matvar->internal->fieldnames[i] = Mat_strdup(fields[i]); - } - } - } - if ( NULL != matvar && nelems > 0 ) { - size_t nelems_x_nfields; - int err = Mul(&nelems_x_nfields, nelems, nfields); - err |= Mul(&matvar->nbytes, nelems_x_nfields, matvar->data_size); - if ( err ) { - Mat_VarFree(matvar); - return NULL; - } - matvar->data = calloc(nelems_x_nfields, matvar->data_size); - } - } - - return matvar; -} - -/** @brief Adds a field to a structure - * - * Adds the given field to the structure. fields should be an array of matvar_t - * pointers of the same size as the structure (i.e. 1 field per structure - * element). - * @ingroup MAT - * @param matvar Pointer to the Structure MAT variable - * @param fieldname Name of field to be added - * @retval 0 on success - */ -int -Mat_VarAddStructField(matvar_t *matvar, const char *fieldname) -{ - int err; - int cnt = 0; - size_t i, nfields, nelems = 1; - matvar_t **new_data, **old_data; - char **fieldnames; - - if ( matvar == NULL || fieldname == NULL ) - return -1; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) - return -1; - - matvar->internal->num_fields++; - nfields = matvar->internal->num_fields; - fieldnames = (char **)realloc(matvar->internal->fieldnames, - nfields * sizeof(*matvar->internal->fieldnames)); - if ( NULL == fieldnames ) - return -1; - matvar->internal->fieldnames = fieldnames; - matvar->internal->fieldnames[nfields - 1] = Mat_strdup(fieldname); - - { - size_t nelems_x_nfields; - err = Mul(&nelems_x_nfields, nelems, nfields); - err |= Mul(&matvar->nbytes, nelems_x_nfields, sizeof(*new_data)); - if ( err ) { - matvar->nbytes = 0; - return -1; - } - } - new_data = (matvar_t **)malloc(matvar->nbytes); - if ( new_data == NULL ) { - matvar->nbytes = 0; - return -1; - } - - old_data = (matvar_t **)matvar->data; - for ( i = 0; i < nelems; i++ ) { - size_t f; - for ( f = 0; f < nfields - 1; f++ ) - new_data[cnt++] = old_data[i * (nfields - 1) + f]; - new_data[cnt++] = NULL; - } - - free(matvar->data); - matvar->data = new_data; - - return 0; -} - -/** @brief Returns the number of fields in a structure variable - * - * Returns the number of fields in the given structure. - * @ingroup MAT - * @param matvar Structure matlab variable - * @returns Number of fields - */ -unsigned -Mat_VarGetNumberOfFields(matvar_t *matvar) -{ - int nfields; - if ( matvar == NULL || matvar->class_type != MAT_C_STRUCT || NULL == matvar->internal ) { - nfields = 0; - } else { - nfields = matvar->internal->num_fields; - } - return nfields; -} - -/** @brief Returns the fieldnames of a structure variable - * - * Returns the fieldnames for the given structure. The returned pointers are - * internal to the structure and should not be free'd. - * @ingroup MAT - * @param matvar Structure matlab variable - * @returns Array of fieldnames - */ -char *const * -Mat_VarGetStructFieldnames(const matvar_t *matvar) -{ - if ( matvar == NULL || matvar->class_type != MAT_C_STRUCT || NULL == matvar->internal ) { - return NULL; - } else { - return matvar->internal->fieldnames; - } -} - -/** @brief Finds a field of a structure by the field's index - * - * Returns a pointer to the structure field at the given 0-relative index. - * @ingroup MAT - * @param matvar Pointer to the Structure MAT variable - * @param field_index 0-relative index of the field. - * @param index linear index of the structure array - * @return Pointer to the structure field on success, NULL on error - */ -matvar_t * -Mat_VarGetStructFieldByIndex(matvar_t *matvar, size_t field_index, size_t index) -{ - int err; - matvar_t *field = NULL; - size_t nelems = 1, nfields; - - if ( matvar == NULL || matvar->class_type != MAT_C_STRUCT || matvar->data_size == 0 ) - return NULL; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) - return NULL; - - nfields = matvar->internal->num_fields; - - if ( nelems > 0 && index >= nelems ) { - Mat_Critical("Mat_VarGetStructField: structure index out of bounds"); - } else if ( nfields > 0 ) { - if ( field_index > nfields ) { - Mat_Critical("Mat_VarGetStructField: field index out of bounds"); - } else { - field = *((matvar_t **)matvar->data + index * nfields + field_index); - } - } - - return field; -} - -/** @brief Finds a field of a structure by the field's name - * - * Returns a pointer to the structure field at the given 0-relative index. - * @ingroup MAT - * @param matvar Pointer to the Structure MAT variable - * @param field_name Name of the structure field - * @param index linear index of the structure array - * @return Pointer to the structure field on success, NULL on error - */ -matvar_t * -Mat_VarGetStructFieldByName(matvar_t *matvar, const char *field_name, size_t index) -{ - int i, nfields, field_index, err; - matvar_t *field = NULL; - size_t nelems = 1; - - if ( matvar == NULL || matvar->class_type != MAT_C_STRUCT || matvar->data_size == 0 ) - return NULL; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) - return NULL; - - nfields = matvar->internal->num_fields; - field_index = -1; - for ( i = 0; i < nfields; i++ ) { - if ( !strcmp(matvar->internal->fieldnames[i], field_name) ) { - field_index = i; - break; - } - } - - if ( index >= nelems ) { - Mat_Critical("Mat_VarGetStructField: structure index out of bounds"); - } else if ( field_index >= 0 ) { - field = *((matvar_t **)matvar->data + index * nfields + field_index); - } - - return field; -} - -/** @brief Finds a field of a structure - * - * Returns a pointer to the structure field at the given 0-relative index. - * @ingroup MAT - * @param matvar Pointer to the Structure MAT variable - * @param name_or_index Name of the field, or the 1-relative index of the field - * If the index is used, it should be the address of an integer variable whose - * value is the index number. - * @param opt MAT_BY_NAME if the name_or_index is the name or MAT_BY_INDEX if - * the index was passed. - * @param index linear index of the structure to find the field of - * @return Pointer to the Structure Field on success, NULL on error - */ -matvar_t * -Mat_VarGetStructField(matvar_t *matvar, void *name_or_index, int opt, int index) -{ - int err, nfields; - matvar_t *field = NULL; - size_t nelems = 1; - - err = Mat_MulDims(matvar, &nelems); - nfields = matvar->internal->num_fields; - if ( index < 0 || (nelems > 0 && (size_t)index >= nelems) ) - err = 1; - else if ( nfields < 1 ) - err = 1; - - if ( !err && (opt == MAT_BY_INDEX) ) { - size_t field_index = *(int *)name_or_index; - if ( field_index > 0 ) - field = Mat_VarGetStructFieldByIndex(matvar, field_index - 1, index); - } else if ( !err && (opt == MAT_BY_NAME) ) { - field = Mat_VarGetStructFieldByName(matvar, (const char *)name_or_index, index); - } - - return field; -} - -/** @brief Indexes a structure - * - * Finds structures of a structure array given a start, stride, and edge for - * each dimension. The structures are placed in a new structure array. If - * copy_fields is non-zero, the indexed structures are copied and should be - * freed, but if copy_fields is zero, the indexed structures are pointers to - * the original, but should still be freed. The structures have a flag set - * so that the structure fields are not freed. - * - * Note that this function is limited to structure arrays with a rank less than - * 10. - * - * @ingroup MAT - * @param matvar Structure matlab variable - * @param start vector of length rank with 0-relative starting coordinates for - * each dimension. - * @param stride vector of length rank with strides for each dimension. - * @param edge vector of length rank with the number of elements to read in - * each dimension. - * @param copy_fields 1 to copy the fields, 0 to just set pointers to them. - * @returns A new structure array with fields indexed from @c matvar. - */ -matvar_t * -Mat_VarGetStructs(matvar_t *matvar, int *start, int *stride, int *edge, int copy_fields) -{ - size_t i, N, I, nfields, field, - idx[10] = - { - 0, - }, - cnt[10] = - { - 0, - }, - dimp[10] = { - 0, - }; - matvar_t **fields, *struct_slab; - int j; - - if ( matvar == NULL || start == NULL || stride == NULL || edge == NULL ) { - return NULL; - } else if ( matvar->rank > 9 ) { - return NULL; - } else if ( matvar->class_type != MAT_C_STRUCT ) { - return NULL; - } - - struct_slab = Mat_VarDuplicate(matvar, 0); - if ( !copy_fields ) - struct_slab->mem_conserve = 1; - - nfields = matvar->internal->num_fields; - - dimp[0] = matvar->dims[0]; - N = edge[0]; - I = start[0]; - struct_slab->dims[0] = edge[0]; - idx[0] = start[0]; - for ( j = 1; j < matvar->rank; j++ ) { - idx[j] = start[j]; - dimp[j] = dimp[j - 1] * matvar->dims[j]; - N *= edge[j]; - I += start[j] * dimp[j - 1]; - struct_slab->dims[j] = edge[j]; - } - I *= nfields; - struct_slab->nbytes = N * nfields * sizeof(matvar_t *); - struct_slab->data = malloc(struct_slab->nbytes); - if ( struct_slab->data == NULL ) { - Mat_VarFree(struct_slab); - return NULL; - } - fields = (matvar_t **)struct_slab->data; - for ( i = 0; i < N; i += edge[0] ) { - for ( j = 0; j < edge[0]; j++ ) { - for ( field = 0; field < nfields; field++ ) { - if ( copy_fields ) - fields[(i + j) * nfields + field] = - Mat_VarDuplicate(*((matvar_t **)matvar->data + I), 1); - else - fields[(i + j) * nfields + field] = *((matvar_t **)matvar->data + I); - I++; - } - I += (stride[0] - 1) * nfields; - } - idx[0] = start[0]; - I = idx[0]; - cnt[1]++; - idx[1] += stride[1]; - for ( j = 1; j < matvar->rank; j++ ) { - if ( cnt[j] == (size_t)edge[j] ) { - cnt[j] = 0; - idx[j] = start[j]; - if ( j < matvar->rank - 1 ) { - cnt[j + 1]++; - idx[j + 1] += stride[j + 1]; - } - } - I += idx[j] * dimp[j - 1]; - } - I *= nfields; - } - return struct_slab; -} - -/** @brief Indexes a structure - * - * Finds structures of a structure array given a single (linear)start, stride, - * and edge. The structures are placed in a new structure array. If - * copy_fields is non-zero, the indexed structures are copied and should be - * freed, but if copy_fields is zero, the indexed structures are pointers to - * the original, but should still be freed since the mem_conserve flag is set - * so that the structures are not freed. - * MAT file version must be 5. - * @ingroup MAT - * @param matvar Structure matlab variable - * @param start starting index (0-relative) - * @param stride stride (1 reads consecutive elements) - * @param edge Number of elements to read - * @param copy_fields 1 to copy the fields, 0 to just set pointers to them. - * @returns A new structure with fields indexed from matvar - */ -matvar_t * -Mat_VarGetStructsLinear(matvar_t *matvar, int start, int stride, int edge, int copy_fields) -{ - matvar_t *struct_slab; - - if ( matvar == NULL || matvar->rank > 10 ) { - struct_slab = NULL; - } else { - int i, I, field, nfields; - matvar_t **fields; - - struct_slab = Mat_VarDuplicate(matvar, 0); - if ( !copy_fields ) - struct_slab->mem_conserve = 1; - - nfields = matvar->internal->num_fields; - - struct_slab->nbytes = (size_t)edge * nfields * sizeof(matvar_t *); - struct_slab->data = malloc(struct_slab->nbytes); - if ( struct_slab->data == NULL ) { - Mat_VarFree(struct_slab); - return NULL; - } - struct_slab->dims[0] = edge; - struct_slab->dims[1] = 1; - fields = (matvar_t **)struct_slab->data; - I = start * nfields; - for ( i = 0; i < edge; i++ ) { - if ( copy_fields ) { - for ( field = 0; field < nfields; field++ ) { - fields[i * nfields + field] = - Mat_VarDuplicate(*((matvar_t **)matvar->data + I), 1); - I++; - } - } else { - for ( field = 0; field < nfields; field++ ) { - fields[i * nfields + field] = *((matvar_t **)matvar->data + I); - I++; - } - } - I += (stride - 1) * nfields; - } - } - return struct_slab; -} - -/** @brief Sets the structure field to the given variable - * - * Sets the structure field specified by the 0-relative field index - * @c field_index for the given 0-relative structure index @c index to - * @c field. - * @ingroup MAT - * @param matvar Pointer to the structure MAT variable - * @param field_index 0-relative index of the field. - * @param index linear index of the structure array - * @param field New field variable - * @return Pointer to the previous field (NULL if no previous field) - */ -matvar_t * -Mat_VarSetStructFieldByIndex(matvar_t *matvar, size_t field_index, size_t index, matvar_t *field) -{ - int err; - matvar_t *old_field = NULL; - size_t nelems = 1, nfields; - - if ( matvar == NULL || matvar->class_type != MAT_C_STRUCT || matvar->data == NULL ) - return NULL; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) - return NULL; - - nfields = matvar->internal->num_fields; - - if ( index < nelems && field_index < nfields ) { - matvar_t **fields = (matvar_t **)matvar->data; - old_field = fields[index * nfields + field_index]; - fields[index * nfields + field_index] = field; - if ( NULL != field->name ) { - free(field->name); - } - field->name = Mat_strdup(matvar->internal->fieldnames[field_index]); - } - - return old_field; -} - -/** @brief Sets the structure field to the given variable - * - * Sets the specified structure fieldname at the given 0-relative @c index to - * @c field. - * @ingroup MAT - * @param matvar Pointer to the Structure MAT variable - * @param field_name Name of the structure field - * @param index linear index of the structure array - * @param field New field variable - * @return Pointer to the previous field (NULL if no previous field) - */ -matvar_t * -Mat_VarSetStructFieldByName(matvar_t *matvar, const char *field_name, size_t index, matvar_t *field) -{ - int err, i, nfields, field_index; - matvar_t *old_field = NULL; - size_t nelems = 1; - - if ( matvar == NULL || matvar->class_type != MAT_C_STRUCT || matvar->data == NULL ) - return NULL; - - err = Mat_MulDims(matvar, &nelems); - if ( err ) - return NULL; - - nfields = matvar->internal->num_fields; - field_index = -1; - for ( i = 0; i < nfields; i++ ) { - if ( !strcmp(matvar->internal->fieldnames[i], field_name) ) { - field_index = i; - break; - } - } - - if ( index < nelems && field_index >= 0 ) { - matvar_t **fields = (matvar_t **)matvar->data; - old_field = fields[index * nfields + field_index]; - fields[index * nfields + field_index] = field; - if ( NULL != field->name ) { - free(field->name); - } - field->name = Mat_strdup(matvar->internal->fieldnames[field_index]); - } - - return old_field; -} - -#endif /* NO_FILE_SYSTEM */ diff --git a/ModelicaExternalC/C-Sources/ModelicaMatIO.h b/ModelicaExternalC/C-Sources/ModelicaMatIO.h deleted file mode 100644 index d77247e35..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaMatIO.h +++ /dev/null @@ -1,462 +0,0 @@ -/* ModelicaMatIO.h - MAT file I/O functions header - - Copyright (C) 2013-2021, Modelica Association and contributors - Copyright (C) 2005-2013, Christopher C. Hulbert - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - This file was created by concatenation of the following header files of the - MAT file I/O library from : - - matio.h - matio_pubconf.h -*/ - -#ifndef MODELICA_MATIO_H_ -#define MODELICA_MATIO_H_ - -#include -#include - -#ifndef MATIO_PUBCONF_H -#define MATIO_PUBCONF_H 1 - -/* Matio major version number */ -#define MATIO_MAJOR_VERSION 1 - -/* Matio minor version number */ -#define MATIO_MINOR_VERSION 5 - -/* Matio release level number */ -#define MATIO_RELEASE_LEVEL 21 - -/* Matio version number */ -#define MATIO_VERSION 1521 - -/* Matio version string */ -#define MATIO_VERSION_STR "1.5.21" - -/* Default file format */ -#define MAT_FT_DEFAULT MAT_FT_MAT5 - -/* Have MAT int64 / uint64 */ -#if defined(_WIN32) -#if defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) || defined(__BORLANDC__) -#define HAVE_MATIO_INT64_T 1 -#define HAVE_MATIO_UINT64_T 1 -#elif defined(_MSC_VER) && _MSC_VER > 1300 -#define HAVE_MATIO_INT64_T 1 -#define HAVE_MATIO_UINT64_T 1 -#elif defined(_MSC_VER) -#define HAVE_MATIO_INT64_T 1 -#undef HAVE_MATIO_UINT64_T -#else -#undef HAVE_MATIO_INT64_T -#undef HAVE_MATIO_UINT64_T -#endif -#else -#define HAVE_MATIO_INT64_T 1 -#define HAVE_MATIO_UINT64_T 1 -#endif - -/* Have the header file */ -#if defined(_WIN32) -#if defined(_MSC_VER) && _MSC_VER >= 1600 -#define HAVE_MATIO_STDINT_H 1 -#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) -#define HAVE_MATIO_STDINT_H 1 -#else -#undef HAVE_MATIO_STDINT_H -#endif -#elif defined(__GNUC__) && !defined(__VXWORKS__) -#define HAVE_MATIO_STDINT_H 1 -#else -#undef HAVE_MATIO_STDINT_H -#endif - -/* Include integer type header */ -#if defined(HAVE_MATIO_STDINT_H) -#include -#elif defined(_MSC_VER) -#define HAVE_MATIO_STDINT_H 1 -#include "stdint_msvc.h" -#endif - -#if defined(HAVE_MATIO_STDINT_H) -typedef int16_t mat_int16_t; -typedef int32_t mat_int32_t; -typedef int64_t mat_int64_t; -typedef int8_t mat_int8_t; -typedef uint16_t mat_uint16_t; -typedef uint32_t mat_uint32_t; -typedef uint64_t mat_uint64_t; -typedef uint8_t mat_uint8_t; -#else -#define mat_int16_t short -#define mat_int32_t int -#if defined(HAVE_MATIO_INT64_T) -#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300) -#define mat_int64_t __int64 -#else -#define mat_int64_t long long -#endif -#endif -#define mat_int8_t signed char -#define mat_uint16_t unsigned short -#define mat_uint32_t unsigned -#if defined(HAVE_MATIO_UINT64_T) -#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300) -#define mat_uint64_t unsigned __int64 -#else -#define mat_uint64_t unsigned long long -#endif -#endif -#define mat_uint8_t unsigned char -#endif - -/* - The following macros handle format attributes for type-checks against a - format string. -*/ - -#if defined(__GNUC__) && __GNUC__ >= 3 -#define MATIO_FORMATATTR_PRINTF1 __attribute__((format(printf, 1, 2))) -#define MATIO_FORMATATTR_VPRINTF __attribute__((format(printf, 1, 0))) -#elif defined(__clang__) -#if __has_attribute(format) -#define MATIO_FORMATATTR_PRINTF1 __attribute__((format(printf, 1, 2))) -#define MATIO_FORMATATTR_VPRINTF __attribute__((format(printf, 1, 0))) -#else -#define MATIO_FORMATATTR_PRINTF1 -#define MATIO_FORMATATTR_VPRINTF -#endif -#else -#define MATIO_FORMATATTR_PRINTF1 -#define MATIO_FORMATATTR_VPRINTF -#endif - -#endif /* MATIO_PUBCONF_H */ - -#include - -#if !defined(MATIO_EXTERN) -#if defined(__cplusplus) -#define MATIO_EXTERN extern "C" -#else -#define MATIO_EXTERN -#endif -#endif - -/** @defgroup MAT Matlab MAT File I/O Library */ -/** @defgroup mat_util MAT File I/O Utility Functions */ -/** @if mat_devman @defgroup mat_internal Internal Functions @endif */ - -/** @brief MAT file access types - * - * @ingroup MAT - * MAT file access types - */ -enum mat_acc -{ - MAT_ACC_RDONLY = 0, /**< @brief Read only file access */ - MAT_ACC_RDWR = 1 /**< @brief Read/Write file access */ -}; - -/** @brief MAT file versions - * - * @ingroup MAT - * MAT file versions - */ -enum mat_ft -{ - MAT_FT_MAT73 = 0x0200, /**< @brief Matlab version 7.3 file */ - MAT_FT_MAT5 = 0x0100, /**< @brief Matlab version 5 file */ - MAT_FT_MAT4 = 0x0010, /**< @brief Matlab version 4 file */ - MAT_FT_UNDEFINED = 0 /**< @brief Undefined version */ -}; - -/** @brief Matlab data types - * - * @ingroup MAT - * Matlab data types - */ -enum matio_types -{ - MAT_T_UNKNOWN = 0, /**< @brief UNKNOWN data type */ - MAT_T_INT8 = 1, /**< @brief 8-bit signed integer data type */ - MAT_T_UINT8 = 2, /**< @brief 8-bit unsigned integer data type */ - MAT_T_INT16 = 3, /**< @brief 16-bit signed integer data type */ - MAT_T_UINT16 = 4, /**< @brief 16-bit unsigned integer data type */ - MAT_T_INT32 = 5, /**< @brief 32-bit signed integer data type */ - MAT_T_UINT32 = 6, /**< @brief 32-bit unsigned integer data type */ - MAT_T_SINGLE = 7, /**< @brief IEEE 754 single precision data type */ - MAT_T_DOUBLE = 9, /**< @brief IEEE 754 double precision data type */ - MAT_T_INT64 = 12, /**< @brief 64-bit signed integer data type */ - MAT_T_UINT64 = 13, /**< @brief 64-bit unsigned integer data type */ - MAT_T_MATRIX = 14, /**< @brief matrix data type */ - MAT_T_COMPRESSED = 15, /**< @brief compressed data type */ - MAT_T_UTF8 = 16, /**< @brief 8-bit Unicode text data type */ - MAT_T_UTF16 = 17, /**< @brief 16-bit Unicode text data type */ - MAT_T_UTF32 = 18, /**< @brief 32-bit Unicode text data type */ - - MAT_T_STRING = 20, /**< @brief String data type */ - MAT_T_CELL = 21, /**< @brief Cell array data type */ - MAT_T_STRUCT = 22, /**< @brief Structure data type */ - MAT_T_ARRAY = 23, /**< @brief Array data type */ - MAT_T_FUNCTION = 24 /**< @brief Function data type */ -}; - -/** @brief Matlab variable classes - * - * @ingroup MAT - * Matlab variable classes - */ -enum matio_classes -{ - MAT_C_EMPTY = 0, /**< @brief Empty array */ - MAT_C_CELL = 1, /**< @brief Matlab cell array class */ - MAT_C_STRUCT = 2, /**< @brief Matlab structure class */ - MAT_C_OBJECT = 3, /**< @brief Matlab object class */ - MAT_C_CHAR = 4, /**< @brief Matlab character array class */ - MAT_C_SPARSE = 5, /**< @brief Matlab sparse array class */ - MAT_C_DOUBLE = 6, /**< @brief Matlab double-precision class */ - MAT_C_SINGLE = 7, /**< @brief Matlab single-precision class */ - MAT_C_INT8 = 8, /**< @brief Matlab signed 8-bit integer class */ - MAT_C_UINT8 = 9, /**< @brief Matlab unsigned 8-bit integer class */ - MAT_C_INT16 = 10, /**< @brief Matlab signed 16-bit integer class */ - MAT_C_UINT16 = 11, /**< @brief Matlab unsigned 16-bit integer class */ - MAT_C_INT32 = 12, /**< @brief Matlab signed 32-bit integer class */ - MAT_C_UINT32 = 13, /**< @brief Matlab unsigned 32-bit integer class */ - MAT_C_INT64 = 14, /**< @brief Matlab signed 64-bit integer class */ - MAT_C_UINT64 = 15, /**< @brief Matlab unsigned 64-bit integer class */ - MAT_C_FUNCTION = 16, /**< @brief Matlab function class */ - MAT_C_OPAQUE = 17 /**< @brief Matlab opaque class */ -}; - -/** @brief Matlab array flags - * - * @ingroup MAT - * Matlab array flags - */ -enum matio_flags -{ - MAT_F_COMPLEX = 0x0800, /**< @brief Complex bit flag */ - MAT_F_GLOBAL = 0x0400, /**< @brief Global bit flag */ - MAT_F_LOGICAL = 0x0200, /**< @brief Logical bit flag */ - MAT_F_DONT_COPY_DATA = 0x0001 /**< Don't copy data, use keep the pointer */ -}; - -/** @brief MAT file compression options - * - * This option is only used on version 5 MAT files - * @ingroup MAT - */ -enum matio_compression -{ - MAT_COMPRESSION_NONE = 0, /**< @brief No compression */ - MAT_COMPRESSION_ZLIB = 1 /**< @brief zlib compression */ -}; - -/** @brief matio lookup type - * - * @ingroup MAT - * matio lookup type - */ -enum -{ - MAT_BY_NAME = 1, /**< Lookup by name */ - MAT_BY_INDEX = 2 /**< Lookup by index */ -}; - -/** @brief Complex data type using split storage - * - * Complex data type using split real/imaginary pointers - * @ingroup MAT - */ -typedef struct mat_complex_split_t -{ - void *Re; /**< Pointer to the real part */ - void *Im; /**< Pointer to the imaginary part */ -} mat_complex_split_t; - -struct _mat_t; -/** @brief Matlab MAT File information - * Contains information about a Matlab MAT file - * @ingroup MAT - */ -typedef struct _mat_t mat_t; - -/* Incomplete definition for private library data */ -struct matvar_internal; - -/** @brief Matlab variable information - * - * Contains information about a Matlab variable - * @ingroup MAT - */ -typedef struct matvar_t -{ - size_t nbytes; /**< Number of bytes for the MAT variable */ - int rank; /**< Rank (Number of dimensions) of the data */ - enum matio_types data_type; /**< Data type (MAT_T_*) */ - int data_size; /**< Bytes / element for the data */ - enum matio_classes class_type; /**< Class type in Matlab (MAT_C_DOUBLE, etc) */ - int isComplex; /**< non-zero if the data is complex, 0 if real */ - int isGlobal; /**< non-zero if the variable is global */ - int isLogical; /**< non-zero if the variable is logical */ - size_t *dims; /**< Array of lengths for each dimension */ - char *name; /**< Name of the variable */ - void *data; /**< Pointer to the data */ - int mem_conserve; /**< 1 if Memory was conserved with data */ - enum matio_compression compression; /**< Variable compression type */ - struct matvar_internal *internal; /**< matio internal data */ -} matvar_t; - -/** @brief sparse data information - * - * Contains information and data for a sparse matrix - * @ingroup MAT - */ -typedef struct mat_sparse_t -{ - mat_uint32_t nzmax; /**< Maximum number of non-zero elements */ - mat_uint32_t *ir; /**< Array of size nzmax where ir[k] is the row of - * data[k]. 0 <= k <= nzmax - */ - mat_uint32_t nir; /**< number of elements in ir */ - mat_uint32_t *jc; /**< Array size N+1 (N is number of columns) with - * jc[k] being the index into ir/data of the - * first non-zero element for row k. - */ - mat_uint32_t njc; /**< Number of elements in jc */ - mat_uint32_t ndata; /**< Number of complex/real data values */ - void *data; /**< Array of data elements */ -} mat_sparse_t; - -/** @cond 0 */ -#define MATIO_E_NO_ERROR 0 -#define MATIO_E_UNKNOWN_ERROR 1 -#define MATIO_E_GENERIC_READ_ERROR 2 -#define MATIO_E_GENERIC_WRITE_ERROR 3 -#define MATIO_E_INDEX_TOO_BIG 4 -#define MATIO_E_FILE_FORMAT_VIOLATION 5 -#define MATIO_E_FAIL_TO_IDENTIFY 6 -#define MATIO_E_BAD_ARGUMENT 7 -#define MATIO_E_OUTPUT_BAD_DATA 8 -#define MATIO_E_OPERATION_NOT_SUPPORTED 13 -#define MATIO_E_OUT_OF_MEMORY 14 -#define MATIO_E_BAD_VARIABLE_NAME 15 -#define MATIO_E_OPERATION_PROHIBITED_IN_WRITE_MODE 16 -#define MATIO_E_OPERATION_PROHIBITED_IN_READ_MODE 17 -#define MATIO_E_WRITE_VARIABLE_DOES_NOT_EXIST 18 -#define MATIO_E_READ_VARIABLE_DOES_NOT_EXIST 19 -#define MATIO_E_FILESYSTEM_COULD_NOT_OPEN 20 -#define MATIO_E_FILESYSTEM_COULD_NOT_OPEN_TEMPORARY 21 -#define MATIO_E_FILESYSTEM_COULD_NOT_REOPEN 22 -#define MATIO_E_BAD_OPEN_MODE 23 -#define MATIO_E_FILESYSTEM_ERROR_ON_CLOSE 24 -/** @endcond */ - -/* Library function */ -MATIO_EXTERN void Mat_GetLibraryVersion(int *major, int *minor, int *release); - -/* io.c */ -MATIO_EXTERN void Mat_Critical(const char *format, ...) MATIO_FORMATATTR_PRINTF1; -MATIO_EXTERN void Mat_Warning(const char *format, ...) MATIO_FORMATATTR_PRINTF1; -MATIO_EXTERN size_t Mat_SizeOf(enum matio_types data_type); -MATIO_EXTERN size_t Mat_SizeOfClass(int class_type); - -/* MAT File functions */ -#define Mat_Create(a, b) Mat_CreateVer(a, b, MAT_FT_DEFAULT) -MATIO_EXTERN mat_t *Mat_CreateVer(const char *matname, const char *hdr_str, - enum mat_ft mat_file_ver); -MATIO_EXTERN int Mat_Close(mat_t *mat); -MATIO_EXTERN mat_t *Mat_Open(const char *matname, int mode); -MATIO_EXTERN const char *Mat_GetFilename(mat_t *mat); -MATIO_EXTERN const char *Mat_GetHeader(mat_t *mat); -MATIO_EXTERN enum mat_ft Mat_GetVersion(mat_t *mat); -MATIO_EXTERN char **Mat_GetDir(mat_t *mat, size_t *n); -MATIO_EXTERN int Mat_Rewind(mat_t *mat); - -/* MAT variable functions */ -MATIO_EXTERN matvar_t *Mat_VarCalloc(void); -MATIO_EXTERN matvar_t *Mat_VarCreate(const char *name, enum matio_classes class_type, - enum matio_types data_type, int rank, size_t *dims, void *data, - int opt); -MATIO_EXTERN matvar_t *Mat_VarCreateStruct(const char *name, int rank, size_t *dims, - const char **fields, unsigned nfields); -MATIO_EXTERN int Mat_VarDelete(mat_t *mat, const char *name); -MATIO_EXTERN matvar_t *Mat_VarDuplicate(const matvar_t *in, int opt); -MATIO_EXTERN void Mat_VarFree(matvar_t *matvar); -MATIO_EXTERN matvar_t *Mat_VarGetCell(matvar_t *matvar, int index); -MATIO_EXTERN matvar_t **Mat_VarGetCells(matvar_t *matvar, int *start, int *stride, int *edge); -MATIO_EXTERN matvar_t **Mat_VarGetCellsLinear(matvar_t *matvar, int start, int stride, int edge); -MATIO_EXTERN size_t Mat_VarGetSize(matvar_t *matvar); -MATIO_EXTERN unsigned Mat_VarGetNumberOfFields(matvar_t *matvar); -MATIO_EXTERN int Mat_VarAddStructField(matvar_t *matvar, const char *fieldname); -MATIO_EXTERN char *const *Mat_VarGetStructFieldnames(const matvar_t *matvar); -MATIO_EXTERN matvar_t *Mat_VarGetStructFieldByIndex(matvar_t *matvar, size_t field_index, - size_t index); -MATIO_EXTERN matvar_t *Mat_VarGetStructFieldByName(matvar_t *matvar, const char *field_name, - size_t index); -MATIO_EXTERN matvar_t *Mat_VarGetStructField(matvar_t *matvar, void *name_or_index, int opt, - int index); -MATIO_EXTERN matvar_t *Mat_VarGetStructs(matvar_t *matvar, int *start, int *stride, int *edge, - int copy_fields); -MATIO_EXTERN matvar_t *Mat_VarGetStructsLinear(matvar_t *matvar, int start, int stride, int edge, - int copy_fields); -MATIO_EXTERN void Mat_VarPrint(matvar_t *matvar, int printdata); -MATIO_EXTERN matvar_t *Mat_VarRead(mat_t *mat, const char *name); -MATIO_EXTERN int Mat_VarReadData(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, - int *edge); -MATIO_EXTERN int Mat_VarReadDataAll(mat_t *mat, matvar_t *matvar); -MATIO_EXTERN int Mat_VarReadDataLinear(mat_t *mat, matvar_t *matvar, void *data, int start, - int stride, int edge); -MATIO_EXTERN matvar_t *Mat_VarReadInfo(mat_t *mat, const char *name); -MATIO_EXTERN matvar_t *Mat_VarReadNext(mat_t *mat); -MATIO_EXTERN matvar_t *Mat_VarReadNextInfo(mat_t *mat); -MATIO_EXTERN matvar_t *Mat_VarSetCell(matvar_t *matvar, int index, matvar_t *cell); -MATIO_EXTERN matvar_t *Mat_VarSetStructFieldByIndex(matvar_t *matvar, size_t field_index, - size_t index, matvar_t *field); -MATIO_EXTERN matvar_t *Mat_VarSetStructFieldByName(matvar_t *matvar, const char *field_name, - size_t index, matvar_t *field); -MATIO_EXTERN int Mat_VarWrite(mat_t *mat, matvar_t *matvar, enum matio_compression compress); -MATIO_EXTERN int Mat_VarWriteAppend(mat_t *mat, matvar_t *matvar, enum matio_compression compress, - int dim); -MATIO_EXTERN int Mat_VarWriteInfo(mat_t *mat, matvar_t *matvar); -MATIO_EXTERN int Mat_VarWriteData(mat_t *mat, matvar_t *matvar, void *data, int *start, int *stride, - int *edge); - -/* Other functions */ -MATIO_EXTERN int Mat_CalcSingleSubscript(int rank, int *dims, int *subs); -MATIO_EXTERN int Mat_CalcSingleSubscript2(int rank, size_t *dims, size_t *subs, size_t *index); -MATIO_EXTERN int *Mat_CalcSubscripts(int rank, int *dims, int index); -MATIO_EXTERN size_t *Mat_CalcSubscripts2(int rank, size_t *dims, size_t index); - -#endif /* MODELICAMATIO_H */ diff --git a/ModelicaExternalC/C-Sources/ModelicaRandom.c b/ModelicaExternalC/C-Sources/ModelicaRandom.c deleted file mode 100644 index 69b0be9fd..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaRandom.c +++ /dev/null @@ -1,429 +0,0 @@ -/* ModelicaRandom.c - External functions for Modelica.Math.Random library - - Copyright (C) 2015-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* Changelog: - Sep. 23, 2016: by Thomas Beutlich, ESI ITI GmbH - Fixed resource leak (ticket #2069) - - Oct. 27, 2015: by Thomas Beutlich, ITI GmbH - Added nonnull attribute/annotations (ticket #1436) - - Feb. 17, 2015: by Andreas Kloeckner and Martin Otter, DLR-SR - Implemented a first version -*/ - -#include "ModelicaRandom.h" -#include "stdint_wrap.h" -#include -#include -#include -#include -#include "ModelicaInternal.h" -#include "ModelicaUtilities.h" -#include "gconstructor.h" - -/* The standard way to detect POSIX is to check _POSIX_VERSION, - * which is defined in - */ -#if defined(__unix__) || defined(__linux__) || defined(__APPLE_CC__) - #include -#endif -#if !defined(_POSIX_) && defined(_POSIX_VERSION) - #define _POSIX_ 1 -#endif - -/* On POSIX systems define a mutex using the single static variable "m" */ -#if defined(_POSIX_) && !defined(NO_MUTEX) -#include -static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; -#define MUTEX_LOCK() pthread_mutex_lock(&m) -#define MUTEX_UNLOCK() pthread_mutex_unlock(&m) - -/* On Windows systems define a critical section using the single static variable "cs" */ -#elif defined(_WIN32) && defined(G_HAS_CONSTRUCTORS) -#if !defined(WIN32_LEAN_AND_MEAN) -#define WIN32_LEAN_AND_MEAN -#endif -#include -static CRITICAL_SECTION cs; -#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA -#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(ModelicaRandom_initializeCS) -#endif -G_DEFINE_CONSTRUCTOR(ModelicaRandom_initializeCS) -static void ModelicaRandom_initializeCS(void) { - InitializeCriticalSection(&cs); -} -#ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA -#pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(ModelicaRandom_deleteCS) -#endif -G_DEFINE_DESTRUCTOR(ModelicaRandom_deleteCS) -static void ModelicaRandom_deleteCS(void) { - DeleteCriticalSection(&cs); -} -#define MUTEX_LOCK() EnterCriticalSection(&cs) -#define MUTEX_UNLOCK() LeaveCriticalSection(&cs) - -/* On other systems do not use a mutex at all */ -#else -#define MUTEX_LOCK() -#define MUTEX_UNLOCK() -#endif - -/* XORSHIFT ALGORITHMS */ - -/* For details see http://xorshift.di.unimi.it/ - - Written in 2014 by Sebastiano Vigna (vigna@acm.org) - - To the extent possible under law, the author has dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - See . - - Adapted by Martin Otter and Andreas Kloeckner for use with Modelica: - - Inputs and outputs must be int's, that is int32_t. - - Inputs are casted accordingly. - - Outputs are casted accordingly. - - The additional double between 0 and 1 is output. -*/ - -/* transform 64-bit unsigned integer to double such that zero cannot appear, by - first transforming to a 64-bit signed integer, then to a double in the range 0 .. 1. - (using the algorithm given here: http://www.doornik.com/research/randomdouble.pdf) */ -#define ModelicaRandom_INVM64 5.42101086242752217004e-20 /* = 2^(-64) */ -#define ModelicaRandom_RAND(INT64) ( (int64_t)(INT64) * ModelicaRandom_INVM64 + 0.5 ) - -void ModelicaRandom_xorshift64star(_In_ int* state_in, - _Out_ int* state_out, _Out_ double* y) { - /* xorshift64* random number generator. - For details see http://xorshift.di.unimi.it/ - - Written in 2014 by Sebastiano Vigna (vigna@acm.org) - - To the extent possible under law, the author has dedicated all copyright - and related and neighboring rights to this software to the public domain - worldwide. This software is distributed without any warranty. - - See . - - Adapted by Martin Otter and Andreas Kloeckner (DLR) - for the Modelica external function interface. - */ - - /* This is a good generator if you're short on memory, but otherwise we - rather suggest to use a xorshift128+ (for maximum speed) or - xorshift1024* (for speed and very long period) generator. */ - - /* Convert inputs */ - union s_tag { - int32_t s32[2]; - uint64_t s64; - } s; - size_t i; - uint64_t x; - for (i=0; i> 12; /* a */ - x ^= x << 25; /* b */ - x ^= x >> 27; /* c */ -#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300) - x = x * 2685821657736338717i64; -#else - x = x * 2685821657736338717LL; -#endif - /* Convert outputs */ - s.s64 = x; - for (i=0; i. - - Adapted by Martin Otter and Andreas Kloeckner (DLR) - for the Modelica external function interface. - */ - - /* This is the fastest generator passing BigCrush without systematic - errors, but due to the relatively short period it is acceptable only - for applications with a very mild amount of parallelism; otherwise, use - a xorshift1024* generator. */ - - /* The state must be seeded so that it is not everywhere zero. If you have - a 64-bit seed, we suggest to pass it twice through MurmurHash3's - avalanching function. */ - - /* Convert inputs */ - union s_tag { - int32_t s32[4]; - uint64_t s64[2]; - } s; - size_t i; - uint64_t s1; - uint64_t s0; - for (i=0; i> 17 ) ^ ( s0 >> 26 ) ) + s0; /* b, c */ - - /* Convert outputs */ - for (i=0; i. - - Adapted by Martin Otter and Andreas Kloeckner (DLR) - for the Modelica external function interface. - */ - - /* This is a fast, top-quality generator. If 1024 bits of state are too - much, try a xorshift128+ or a xorshift64* generator. */ - - /* The state must be seeded so that it is not everywhere zero. If you have - a 64-bit seed, we suggest to seed a xorshift64* generator and use its - output to fill s. */ - - /* Convert inputs */ - uint64_t s0; - uint64_t s1; - *p = *p & 15; - - /* The actual algorithm */ - s0 = s[*p]; - s1 = s[*p = (*p + 1) & 15]; - - s1 ^= s1 << 31; /* a */ - s1 ^= s1 >> 11; /* b */ - s0 ^= s0 >> 30; /* c */ - - s[*p] = s0 ^ s1; - - /* Convert outputs */ -#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300) - *y = ModelicaRandom_RAND(s[*p]*1181783497276652981i64); -#else - *y = ModelicaRandom_RAND(s[*p]*1181783497276652981LL); -#endif -} - -void ModelicaRandom_xorshift1024star(_In_ int* state_in, - _Out_ int* state_out, _Out_ double* y) { - /* xorshift1024* random number generator. - For details see http://xorshift.di.unimi.it - - This function uses ModelicaRandom_xorshift1024star_internal as generator and adapts inputs and outputs. - - Adapted by Martin Otter and Andreas Kloeckner (DLR) - for the Modelica external function interface. - */ - - /* This is a fast, top-quality generator. If 1024 bits of state are too - much, try a xorshift128+ or a xorshift64* generator. */ - - /* The state must be seeded so that it is not everywhere zero. If you have - a 64-bit seed, we suggest to seed a xorshift64* generator and use its - output to fill s. */ - - /* Convert inputs */ - union s_tag { - int32_t s32[32]; - uint64_t s64[16]; - } s; - size_t i; - int p; - for (i=0; i ModelicaRandom_size ) { - ModelicaFormatError("External state vector is too large. Should be %lu.\n", (unsigned long)ModelicaRandom_size); - } - MUTEX_LOCK(); - for (i=0; i<16; i++) { - s.s32[0] = state[2*i]; - s.s32[1] = state[2*i+1]; - ModelicaRandom_s[i] = s.s64; - } - ModelicaRandom_p = state[32]; - ModelicaRandom_id = id; - MUTEX_UNLOCK(); -} - -double ModelicaRandom_impureRandom_xorshift1024star(int id) { - /* xorshift1024* random number generator (same as above, but with internal state, instead of external one). - For details see http://xorshift.di.unimi.it - - Argument "id" is provided to guarantee the right calling sequence - of the function in a Modelica environment (first calling function - ModelicaRandom_initialize_xorshift1024star that must return "dummy" which is passed - as input argument to ModelicaRandom_xorshift1024star. As a result, the ordering - of the function is correct. - - This function uses ModelicaRandom_xorshift1024star_internal as generator and adapts inputs and outputs. - - Adapted by Martin Otter (DLR) to initialize the seed with ModelicaRandom_initializeRandom - and to return a double in range 0 < randomNumber < 1.0 - */ - - /* This is a fast, top-quality generator. If 1024 bits of state are too - much, try a xorshift128+ or a xorshift64* generator. */ - - /* The state must be seeded so that it is not everywhere zero. If you have - a 64-bit seed, we suggest to seed a xorshift64* generator and use its - output to fill s. */ - - MUTEX_LOCK(); - /* Check that ModelicaRandom_initializeImpureRandome_xorshift1024star was called before */ - if ( id != ModelicaRandom_id ) { - MUTEX_UNLOCK(); - ModelicaError("Function impureRandom not initialized with function initializeImpureRandom\n"); - return 0; - } - else { - /* Compute random number */ - double y; - ModelicaRandom_xorshift1024star_internal(ModelicaRandom_s, &ModelicaRandom_p, &y); - MUTEX_UNLOCK(); - return y; - } -} - -int ModelicaRandom_automaticGlobalSeed(double dummy) { - /* Creates an automatic integer seed (typically from the current time and process id) */ - - int ms, sec, min, hour, mday, mon, year; - int pid; - int seed; - - ModelicaInternal_getTime(&ms, &sec, &min, &hour, &mday, &mon, &year); - pid = ModelicaInternal_getpid(); - - /* Check that worst case combination can be included in an Integer: - - 1000*60*60 = 3.6e6 < 2^31 = 2147483648 (2.1e9) - - Everything is added to 1, in order to guard against the very unlikely case that the sum is zero. - */ - seed = 1 + ms + 1000*sec + 1000*60*min + 1000*60*60*hour + 6007*pid; - return seed; -} - -void ModelicaRandom_convertRealToIntegers(double d, _Out_ int* i) { - /* Cast a double to two integers */ - union d2i { - double d; - int i[2]; - } u; - - u.d = d; - i[0] = u.i[0]; - i[1] = u.i[1]; -} diff --git a/ModelicaExternalC/C-Sources/ModelicaRandom.h b/ModelicaExternalC/C-Sources/ModelicaRandom.h deleted file mode 100644 index 2b8f5c7d6..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaRandom.h +++ /dev/null @@ -1,85 +0,0 @@ -/* ModelicaRandom.h - External functions header for Modelica.Math.Random library - - Copyright (C) 2015-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* The following #define's are available. - - NO_MUTEX : Pthread mutex is not present (e.g. on dSPACE) - MODELICA_EXPORT: Prefix used for function calls. If not defined, blank is used - Useful definition: - - "__declspec(dllexport)" if included in a DLL and the - functions shall be visible outside of the DLL -*/ - -#ifndef MODELICA_RANDOM_H_ -#define MODELICA_RANDOM_H_ - -#include - -#if !defined(MODELICA_EXPORT) -#if defined(__cplusplus) -#define MODELICA_EXPORT extern "C" -#else -#define MODELICA_EXPORT -#endif -#endif - -/* - * Non-null pointers need to be passed to external functions. - * - * The following macros handle nonnull attributes for GNU C and Microsoft SAL. - */ -#undef MODELICA_NONNULLATTR -#if defined(__GNUC__) -#define MODELICA_NONNULLATTR __attribute__((nonnull)) -#else -#define MODELICA_NONNULLATTR -#endif -#if !defined(__ATTR_SAL) -#undef _In_ -#undef _Out_ -#define _In_ -#define _Out_ -#endif - -MODELICA_EXPORT void ModelicaRandom_xorshift64star(_In_ int* state_in, - _Out_ int* state_out, _Out_ double* y) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaRandom_xorshift128plus(_In_ int* state_in, - _Out_ int* state_out, _Out_ double* y) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaRandom_xorshift1024star(_In_ int* state_in, - _Out_ int* state_out, _Out_ double* y) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaRandom_setInternalState_xorshift1024star( - _In_ int* state, size_t nState, int id) MODELICA_NONNULLATTR; -MODELICA_EXPORT double ModelicaRandom_impureRandom_xorshift1024star(int id); -MODELICA_EXPORT int ModelicaRandom_automaticGlobalSeed(double dummy); -MODELICA_EXPORT void ModelicaRandom_convertRealToIntegers(double d, - _Out_ int* i) MODELICA_NONNULLATTR; - -#endif diff --git a/ModelicaExternalC/C-Sources/ModelicaStandardTables.c b/ModelicaExternalC/C-Sources/ModelicaStandardTables.c deleted file mode 100644 index e0cca82cc..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaStandardTables.c +++ /dev/null @@ -1,7392 +0,0 @@ -/* ModelicaStandardTables.c - External table functions - - Copyright (C) 2013-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* Implementation of external functions for table computation - in the Modelica Standard Library: - - Modelica.Blocks.Sources.CombiTimeTable - Modelica.Blocks.Tables.CombiTable1Ds - Modelica.Blocks.Tables.CombiTable1Dv - Modelica.Blocks.Tables.CombiTable2Ds - Modelica.Blocks.Tables.CombiTable2Dv - - Changelog: - Dec. 22, 2020: by Thomas Beutlich - Added reading of CSV files (ticket #1153) - - May 27, 2020: by Thomas Beutlich - Fixed invalid memory access in error messages of - isValidCombiTimeTable and isValidCombiTable1D (ticket #3562) - - Nov. 01, 2019: by Thomas Beutlich - Added univariate Makima-spline interpolation (ticket #1039) - - Aug. 03, 2019: by Thomas Beutlich - Added second derivatives (ticket #2901) - - Oct. 04, 2018: by Thomas Beutlich, ESI ITI GmbH - Fixed event detection of CombiTimeTable (ticket #2724) - Fixed left extrapolation of CombiTimeTable (ticket #2724) - - Jan. 03, 2018: by Thomas Beutlich, ESI ITI GmbH - Improved reentrancy of CombiTimeTable (ticket #2411) - - Oct. 23, 2017: by Thomas Beutlich, ESI ITI GmbH - Utilized non-fatal hash insertion, called by HASH_ADD_KEYPTR - in function readTable (ticket #2097) - - Aug. 25, 2017: by Thomas Beutlich, ESI ITI GmbH - Added support for extrapolation in CombiTable2D (ticket #1839) - - Apr. 24, 2017: by Thomas Beutlich, ESI ITI GmbH - Added functions to retrieve minimum and maximum abscissa - values of CombiTable2D (ticket #2244) - - Apr. 15, 2017: by Thomas Beutlich, ESI ITI GmbH - Added support for time event generation (independent of - smoothness) in CombiTimeTable (ticket #2080) - - Apr. 11, 2017: by Thomas Beutlich, ESI ITI GmbH - Revised initialization of CombiTimeTable, CombiTable1D - and CombiTable2D (ticket #1899) - - Already read table in the initialization functions - - Apr. 07, 2017: by Thomas Beutlich, ESI ITI GmbH - Added support for shift time (independent of start time) - in CombiTimeTable (ticket #1771) - - Apr. 05, 2017: by Thomas Beutlich, ESI ITI GmbH - Fixed extrapolation of CombiTimeTable if simulation start - time equals the maximum time of the table (ticket #2233) - - Mar. 08, 2017: by Thomas Beutlich, ESI ITI GmbH - Moved file I/O functions to ModelicaIO (ticket #2192) - - Feb. 25, 2017: by Thomas Beutlich, ESI ITI GmbH - Added support for extrapolation in CombiTable1D (ticket #1839) - Added functions to retrieve minimum and maximum abscissa - values of CombiTable1D (ticket #2120) - - Aug. 10, 2016: by Thomas Beutlich, ESI ITI GmbH - Fixed event detection of CombiTimeTable for restarted - simulation (ticket #2040) - Fixed tracing time events (DEBUG_TIME_EVENTS) of CombiTimeTable - for negative simulation time - - Dec. 16, 2015: by Thomas Beutlich, ITI GmbH - Added univariate Steffen-spline interpolation (ticket #1814) - - Nov. 25, 2015: by Thomas Beutlich, ITI GmbH - Added support of struct variables of MATLAB MAT-files - (ticket #1840) - - Nov. 16, 2015: by Thomas Beutlich, ITI GmbH - Fixed support of 2x3 and 3x2 2D tables with spline - interpolation (ticket #1820) - - Nov. 03, 2015: by Thomas Beutlich, ITI GmbH - Added range checks for column indices of CombiTimeTable and - CombiTable1D (ticket #1816) - - Aug. 31, 2015: by Thomas Beutlich, ITI GmbH - Fixed event detection of CombiTimeTable when using a fixed time - step integrator with a step size greater than the event - resolution of the table (ticket #1768) - - May 11, 2015: by Thomas Beutlich, ITI GmbH - Added univariate Fritsch-Butland-spline interpolation - (ticket #1717) - - Apr. 16, 2015: by Thomas Beutlich, ITI GmbH - Fixed event detection of CombiTimeTable with scaled time - (ticket #1627) - - Mar. 18, 2015: by Thomas Beutlich, ITI GmbH - Fixed poor performance of readMatTable for MATLAB MAT-files with - compressed array streams and large (> 1e5) number of rows - (ticket #1682) - - Jan. 02, 2015: by Thomas Beutlich, ITI GmbH - Fixed event detection of CombiTimeTable with non-zero start time - (ticket #1619) - - Aug. 22, 2014: by Thomas Beutlich, ITI GmbH - Fixed multi-threaded access of common/shared table arrays - (ticket #1556) - - Aug. 07, 2014: by Thomas Beutlich, ITI GmbH - Added pure C implementation of common/shared table arrays - (ticket #1550) - - May 21, 2014: by Thomas Beutlich, ITI GmbH - Fixed bivariate Akima-spline extrapolation (ticket #1465) - Improved error message in case of trailing numbers when parsing - a line of a text file (ticket #1494) - - Oct. 17, 2013: by Thomas Beutlich, ITI GmbH - Added support of 2D tables that actually degrade to 1D tables - (ticket #1307) - - Sep. 05, 2013: by Thomas Beutlich, ITI GmbH - Fixed ANSI-C compliance (ticket #1263) - Fixed reading table files with Windows line endings on Linux - (ticket #1264) - - Apr. 09, 2013: by Thomas Beutlich, ITI GmbH - Implemented a first version -*/ - -#include "ModelicaStandardTables.h" -#include "ModelicaIO.h" -#include "ModelicaUtilities.h" -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) -#include "stdint_wrap.h" -#define HASH_NO_STDINT 1 -#define uthash_strlen(s) key_strlen(s) -#define HASH_NONFATAL_OOM 1 -#include "uthash.h" -#include "gconstructor.h" -#endif -#include -#include -#include - -#if !defined(NO_FILE_SYSTEM) -/* The standard way to detect POSIX is to check _POSIX_VERSION, - * which is defined in - */ -#if defined(__unix__) || defined(__linux__) || defined(__APPLE_CC__) -#include -#endif -#if !defined(_POSIX_) && defined(_POSIX_VERSION) -#define _POSIX_ 1 -#endif -#endif - -/* ----- Interface enumerations ----- */ - -enum Smoothness { - LINEAR_SEGMENTS = 1, - CONTINUOUS_DERIVATIVE, - CONSTANT_SEGMENTS, - FRITSCH_BUTLAND_MONOTONE_C1, - STEFFEN_MONOTONE_C1, - MAKIMA_C1, - AKIMA_C1 = CONTINUOUS_DERIVATIVE -}; - -enum Extrapolation { - HOLD_LAST_POINT = 1, - LAST_TWO_POINTS, - PERIODIC, - NO_EXTRAPOLATION -}; - -enum TimeEvents { - UNDEFINED = 0, - ALWAYS, - AT_DISCONT, - NO_TIMEEVENTS -}; - -/* ----- Internal enumerations ----- */ - -enum PointInterval { - LEFT = -1, - IN_TABLE = 0, - RIGHT = 1 -}; - -enum TableSource { - TABLESOURCE_MODEL = 1, - TABLESOURCE_FILE, - TABLESOURCE_FUNCTION, - TABLESOURCE_FUNCTION_TRANSPOSE -}; - -enum CleanUp { - NO_CLEANUP = 0, - DO_CLEANUP -}; - -/* ----- Internal table memory ----- */ - -/* 3 (of 4) 1D cubic Hermite spline coefficients (per interval) */ -typedef double CubicHermite1D[3]; - -/* 15 (of 16) 2D cubic Hermite spline coefficients (per grid) */ -typedef double CubicHermite2D[15]; - -/* Left and right interval indices (per interval) */ -typedef size_t Interval[2]; - -typedef struct CombiTimeTable { - char* key; /* Key consisting of concatenated names of file and table */ - double* table; /* Table values */ - size_t nRow; /* Number of rows of table */ - size_t nCol; /* Number of columns of table */ - size_t last; /* Last accessed row index of table */ - enum Smoothness smoothness; /* Smoothness kind */ - enum Extrapolation extrapolation; /* Extrapolation kind */ - enum TableSource source; /* Source kind */ - enum TimeEvents timeEvents; /* Kind of time event handling */ - int* cols; /* Columns of table to be interpolated */ - size_t nCols; /* Number of columns of table to be interpolated */ - double startTime; /* Start time of inter-/extrapolation */ - double shiftTime; /* Shift time of first table column */ - CubicHermite1D* spline; /* Pre-calculated cubic Hermite spline coefficients, - only used if smoothness is AKIMA_C1 or MAKIMA_C1 or - FRITSCH_BUTLAND_MONOTONE_C1 or STEFFEN_MONOTONE_C1 */ - size_t nEvent; /* Time event counter, discrete */ - double preNextTimeEvent; /* Time of previous time event, discrete */ - double preNextTimeEventCalled; /* Time of previous call of - ModelicaStandardTables_CombiTimeTable_nextTimeEvent, discrete */ - size_t maxEvents; /* Maximum number of time events (per period/cycle) */ - size_t eventInterval; /* Event interval marker, discrete, - In case of periodic extrapolation this is the current event interval, - otherwise it is the next event interval. */ - double tOffset; /* Time offset, calculated by floor function, discrete, - only used if extrapolation is PERIODIC */ - Interval* intervals; /* Event interval indices */ -} CombiTimeTable; - -typedef struct CombiTable1D { - char* key; /* Key consisting of concatenated names of file and table */ - double* table; /* Table values */ - size_t nRow; /* Number of rows of table */ - size_t nCol; /* Number of columns of table */ - size_t last; /* Last accessed row index of table */ - enum Smoothness smoothness; /* Smoothness kind */ - enum Extrapolation extrapolation; /* Extrapolation kind */ - enum TableSource source; /* Source kind */ - int* cols; /* Columns of table to be interpolated */ - size_t nCols; /* Number of columns of table to be interpolated */ - CubicHermite1D* spline; /* Pre-calculated cubic Hermite spline coefficients, - only used if smoothness is AKIMA_C1 or MAKIMA_C1 or - FRITSCH_BUTLAND_MONOTONE_C1 or STEFFEN_MONOTONE_C1 */ -} CombiTable1D; - -typedef struct CombiTable2D { - char* key; /* Key consisting of concatenated names of file and table */ - double* table; /* Table values */ - size_t nRow; /* Number of rows of table */ - size_t nCol; /* Number of columns of table */ - size_t last1; /* Last accessed row index of table */ - size_t last2; /* Last accessed column index of table */ - enum Smoothness smoothness; /* Smoothness kind */ - enum Extrapolation extrapolation; /* Extrapolation kind */ - enum TableSource source; /* Source kind */ - CubicHermite2D* spline; /* Pre-calculated cubic Hermite spline coefficients, - only used if smoothness is AKIMA_C1 */ -} CombiTable2D; - -/* ----- Internal constants ----- */ - -#if !defined(_EPSILON) -#define _EPSILON (1e-10) -#endif -#if !defined(MAX_TABLE_DIMENSIONS) -#define MAX_TABLE_DIMENSIONS (3) -#endif - -/* ----- Internal shortcuts ----- */ - -#define IDX(i, j, n) ((i)*(n) + (j)) -#define TABLE(i, j) table[IDX(i, j, nCol)] -#define TABLE_ROW0(j) table[j] -#define TABLE_COL0(i) table[(i)*nCol] - -#define LINEAR(u, u0, u1, y0, y1) \ -do {\ - y = (y0) + ((y1) - (y0))*((u) - (u0))/((u1) - (u0)); \ -} while(0) -/* -LINEAR(u0, ...) -> y0 -LINEAR(u1, ...) -> y1 -*/ - -#define LINEAR_SLOPE(y0, dy_du, du) \ -do {\ - y = (y0) + (dy_du)*(du); \ -} while(0) - -#define BILINEAR(u1, u2) \ -do {\ - const double u10 = TABLE_COL0(last1 + 1); \ - const double u11 = TABLE_COL0(last1 + 2); \ - const double u20 = TABLE_ROW0(last2 + 1); \ - const double u21 = TABLE_ROW0(last2 + 2); \ - const double y00 = TABLE(last1 + 1, last2 + 1); \ - const double y01 = TABLE(last1 + 1, last2 + 2); \ - const double y10 = TABLE(last1 + 2, last2 + 1); \ - const double y11 = TABLE(last1 + 2, last2 + 2); \ - const double tmp = ((u2) - u20)/(u20 - u21); \ - y = y00 + tmp*(y00 - y01) + ((u1) - u10)/(u10 - u11)* \ - ((1 + tmp)*(y00 - y10) + tmp*(y11 - y01)); \ -} while(0) -/* -BILINEAR(u10, u20, ...) -> y00 -BILINEAR(u10, u21, ...) -> y01 -BILINEAR(u11, u20, ...) -> y10 -BILINEAR(u11, u21, ...) -> y11 -*/ - -#define BILINEAR_DER(u1, u2) \ -do {\ - const double u10 = TABLE_COL0(last1 + 1); \ - const double u11 = TABLE_COL0(last1 + 2); \ - const double u20 = TABLE_ROW0(last2 + 1); \ - const double u21 = TABLE_ROW0(last2 + 2); \ - const double y00 = TABLE(last1 + 1, last2 + 1); \ - const double y01 = TABLE(last1 + 1, last2 + 2); \ - const double y10 = TABLE(last1 + 2, last2 + 1); \ - const double y11 = TABLE(last1 + 2, last2 + 2); \ - der_y = der_u1*(u21*(y10 - y00) + u20*(y01 - y11) + \ - (u2)*(y00 - y01 - y10 + y11)); \ - der_y += der_u2*(u11*(y01 - y00) + u10*(y10 - y11) + \ - (u1)*(y00 - y01 - y10 + y11)); \ - der_y /= (u10 - u11); \ - der_y /= (u20 - u21); \ -} while(0) - -#define BILINEAR_DER2(u1, u2) \ -do {\ - const double u10 = TABLE_COL0(last1 + 1); \ - const double u11 = TABLE_COL0(last1 + 2); \ - const double u20 = TABLE_ROW0(last2 + 1); \ - const double u21 = TABLE_ROW0(last2 + 2); \ - const double y00 = TABLE(last1 + 1, last2 + 1); \ - const double y01 = TABLE(last1 + 1, last2 + 2); \ - const double y10 = TABLE(last1 + 2, last2 + 1); \ - const double y11 = TABLE(last1 + 2, last2 + 2); \ - der2_y = der2_u1*(u21*(y10 - y00) + u20*(y01 - y11) + \ - (u2)*(y00 - y01 - y10 + y11)); \ - der2_y += der2_u2*(u11*(y01 - y00) + u10*(y10 - y11) + \ - (u1)*(y00 - y01 - y10 + y11)); \ - der2_y += 2*der_u1*der_u2*(y00 - y01 - y10 + y11); \ - der2_y /= (u10 - u11); \ - der2_y /= (u20 - u21); \ -} while(0) - -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) -typedef struct TableShare { - char* key; /* Key consisting of concatenated names of file and table */ - size_t refCount; /* Reference counter */ - size_t nRow; /* Number of rows of table */ - size_t nCol; /* Number of columns of table */ - double* table; /* Table values */ - UT_hash_handle hh; /* Hashable structure */ -} TableShare; - -/* ----- Static variables ----- */ - -static TableShare* tableShare = NULL; -#if defined(_POSIX_) && !defined(NO_MUTEX) -#include -#if defined(G_HAS_CONSTRUCTORS) -static pthread_mutex_t m; -G_DEFINE_CONSTRUCTOR(initializeMutex) -static void initializeMutex(void) { - if (pthread_mutex_init(&m, NULL) != 0) { - ModelicaError("Initialization of mutex failed\n"); - } -} -G_DEFINE_DESTRUCTOR(destroyMutex) -static void destroyMutex(void) { - if (pthread_mutex_destroy(&m) != 0) { - ModelicaError("Destruction of mutex failed\n"); - } -} -#else -static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; -#endif -#define MUTEX_LOCK() pthread_mutex_lock(&m) -#define MUTEX_UNLOCK() pthread_mutex_unlock(&m) -#elif defined(_WIN32) && defined(G_HAS_CONSTRUCTORS) -#if !defined(WIN32_LEAN_AND_MEAN) -#define WIN32_LEAN_AND_MEAN -#endif -#include -static CRITICAL_SECTION cs; -#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA -#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(ModelicaStandardTables_initializeCS) -#endif -G_DEFINE_CONSTRUCTOR(ModelicaStandardTables_initializeCS) -static void ModelicaStandardTables_initializeCS(void) { - InitializeCriticalSection(&cs); -} -#ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA -#pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(ModelicaStandardTables_deleteCS) -#endif -G_DEFINE_DESTRUCTOR(ModelicaStandardTables_deleteCS) -static void ModelicaStandardTables_deleteCS(void) { - DeleteCriticalSection(&cs); -} -#define MUTEX_LOCK() EnterCriticalSection(&cs) -#define MUTEX_UNLOCK() LeaveCriticalSection(&cs) -#else -#define MUTEX_LOCK() -#define MUTEX_UNLOCK() -#endif -#endif - -/* ----- Function declarations ----- */ - -extern int usertab(char* tableName, int nipo, int dim[], int* colWise, - double** table); - /* Define tables by statically storing them in function usertab. - This function can be adapted by the user to his/her needs. - - -> tableName: Name of table - -> nipo : = 0: time-table required (time interpolation) - = 1: 1D-table required - = 2: 2D-table required - <- dim: Actual values of dimensions - <- colWise: = 0: table stored row-wise (row_1, row_2, ..., row_n) - = 1: table stored column-wise (column_1, column_2, ...) - <- table: Pointer to vector containing a matrix with dimensions "dim" - <- RETURN: = 0: No error - = 1: An error occurred. An error message is printed from usertab. - */ - -static int isNearlyEqual(double x, double y); - /* Compare two floating-point numbers by threshold _EPSILON */ - -static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, - size_t last, double x); - /* Find the row index i using binary search such that - * i + 1 < nRow - * table[i*nCol] <= x - * table[(i + 1)*nCol] > x for i + 2 < nRow - */ - -static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, - double x) MODELICA_NONNULLATTR; - /* Same as findRowIndex but works on rows */ - -static int isValidName(_In_z_ const char* name) MODELICA_NONNULLATTR; - /* Check, whether a file or table name is valid */ - -static int isValidCombiTimeTable(CombiTimeTable* tableID, - _In_z_ const char* tableName, enum CleanUp cleanUp); - /* Check, whether a CombiTimeTable is well parameterized */ - -static int isValidCombiTable1D(CombiTable1D* tableID, - _In_z_ const char* tableName, enum CleanUp cleanUp); - /* Check, whether a CombiTable1D is well parameterized */ - -static int isValidCombiTable2D(CombiTable2D* tableID, - _In_z_ const char* tableName, enum CleanUp cleanUp); - /* Check, whether a CombiTable2D is well parameterized */ - -static enum TableSource getTableSource(_In_z_ const char* fileName, - _In_z_ const char* tableName) MODELICA_NONNULLATTR; - /* Determine table source (file, model or "usertab" function) from table - and file names - */ - -static void transpose(_Inout_ double* table, size_t nRow, size_t nCol) MODELICA_NONNULLATTR; - /* Cycle-based in-place array transposition */ - -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) -static size_t key_strlen(_In_z_ const char *s); - /* Special strlen for key consisting of concatenated names of file and table */ -#endif - -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) -#define READ_RESULT TableShare* -#else -#define READ_RESULT double* -#endif -static READ_RESULT readTable(_In_z_ const char* fileName, _In_z_ const char* tableName, - _Inout_ size_t* nRow, _Inout_ size_t* nCol, int verbose, - int force, _In_z_ const char* delimiter, - int nHeaderLines) MODELICA_NONNULLATTR; - /* Read a table from a text or MATLAB MAT-file - - <- RETURN: Pointer to TableShare structure or - pointer to array (row-wise storage) of table values - */ - -static CubicHermite1D* akimaSpline1DInit(_In_ const double* table, size_t nRow, - size_t nCol, _In_ const int* cols, - size_t nCols) MODELICA_NONNULLATTR; - /* Calculate the coefficients for univariate cubic Hermite spline - interpolation with the Akima slope approximation - - <- RETURN: Pointer to array of coefficients - */ - -static CubicHermite1D* makimaSpline1DInit(_In_ const double* table, size_t nRow, - size_t nCol, _In_ const int* cols, - size_t nCols) MODELICA_NONNULLATTR; - /* Calculate the coefficients for univariate cubic Hermite spline - interpolation with the modified Akima slope approximation - - <- RETURN: Pointer to array of coefficients - */ - -static CubicHermite1D* fritschButlandSpline1DInit(_In_ const double* table, - size_t nRow, size_t nCol, - _In_ const int* cols, - size_t nCols) MODELICA_NONNULLATTR; - /* Calculate the coefficients for univariate cubic Hermite spline - interpolation with the Fritsch-Butland slope approximation - - <- RETURN: Pointer to array of coefficients - */ - -static CubicHermite1D* steffenSpline1DInit(_In_ const double* table, - size_t nRow, size_t nCol, - _In_ const int* cols, - size_t nCols) MODELICA_NONNULLATTR; - /* Calculate the coefficients for univariate cubic Hermite spline - interpolation with the Steffen slope approximation - - <- RETURN: Pointer to array of coefficients - */ - -static void spline1DClose(CubicHermite1D** spline); - /* Free allocated memory of the 1D cubic Hermite spline coefficients */ - -static CubicHermite2D* spline2DInit(_In_ const double* table, size_t nRow, - size_t nCol) MODELICA_NONNULLATTR; - /* Calculate the coefficients for bivariate cubic Hermite spline - interpolation with the Akima algorithm - - <- RETURN: Pointer to array of coefficients - */ - -static void spline2DClose(CubicHermite2D** spline); - /* Free allocated memory of the 2D cubic Hermite spline coefficients */ - -/* ----- Interface functions ----- */ - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wtautological-compare" -#endif - -void* ModelicaStandardTables_CombiTimeTable_init(_In_z_ const char* tableName, - _In_z_ const char* fileName, - _In_ double* table, size_t nRow, - size_t nColumn, - double startTime, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation) { - return ModelicaStandardTables_CombiTimeTable_init2(fileName, - tableName, table, nRow, nColumn, startTime, columns, nCols, smoothness, - extrapolation, startTime, ALWAYS, 1 /* verbose */); -} - -void* ModelicaStandardTables_CombiTimeTable_init2(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, - double startTime, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation, - double shiftTime, - int timeEvents, - int verbose) { - return ModelicaStandardTables_CombiTimeTable_init3(fileName, - tableName, table, nRow, nColumn, startTime, columns, nCols, smoothness, - extrapolation, shiftTime, timeEvents, verbose, ",", 0); -} - -void* ModelicaStandardTables_CombiTimeTable_init3(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, - double startTime, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation, - double shiftTime, - int timeEvents, - int verbose, - _In_z_ const char* delimiter, - int nHeaderLines) { - CombiTimeTable* tableID; -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - TableShare* file = NULL; - char* keyFile = NULL; -#endif - double* tableFile = NULL; - size_t nRowFile = 0; - size_t nColFile = 0; - enum TableSource source = getTableSource(fileName, tableName); - - /* Read table from file before any other heap allocation */ - if (TABLESOURCE_FILE == source) { -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - file = readTable(fileName, tableName, &nRowFile, &nColFile, verbose, 0, delimiter, nHeaderLines); - if (NULL != file) { - keyFile = file->key; - tableFile = file->table; - } - else { - return NULL; - } -#else - tableFile = readTable(fileName, tableName, &nRowFile, &nColFile, verbose, 0, delimiter, nHeaderLines); - if (NULL == tableFile) { - return NULL; - } -#endif - } - - tableID = (CombiTimeTable*)calloc(1, sizeof(CombiTimeTable)); - if (NULL == tableID) { -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - if (NULL != file) { - MUTEX_LOCK(); - if (--file->refCount == 0) { - ModelicaIO_freeRealTable(file->table); - free(file->key); - HASH_DEL(tableShare, file); - free(file); - } - MUTEX_UNLOCK(); - } -#else - if (NULL != tableFile) { - free(tableFile); - } -#endif - ModelicaError("Memory allocation error\n"); - return NULL; - } - - tableID->smoothness = (enum Smoothness)smoothness; - tableID->extrapolation = (enum Extrapolation)extrapolation; - tableID->timeEvents = (enum TimeEvents)timeEvents; - tableID->nCols = nCols; - tableID->startTime = startTime; - tableID->shiftTime = shiftTime; - tableID->preNextTimeEvent = -DBL_MAX; - tableID->preNextTimeEventCalled = -DBL_MAX; - tableID->source = source; - - switch (tableID->source) { - case TABLESOURCE_FILE: -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - tableID->key = keyFile; -#else - { - size_t lenFileName = strlen(fileName); - tableID->key = (char*)malloc((lenFileName + strlen(tableName) + 2)*sizeof(char)); - if (NULL != tableID->key) { - strcpy(tableID->key, fileName); - strcpy(tableID->key + lenFileName + 1, tableName); - } - } -#endif - tableID->nRow = nRowFile; - tableID->nCol = nColFile; - tableID->table = tableFile; - break; - - case TABLESOURCE_MODEL: - tableID->nRow = nRow; - tableID->nCol = nColumn; -#if defined(NO_TABLE_COPY) - tableID->table = table; -#else - tableID->table = (double*)malloc(nRow*nColumn*sizeof(double)); - if (NULL != tableID->table) { - memcpy(tableID->table, table, nRow*nColumn*sizeof(double)); - } - else { - ModelicaStandardTables_CombiTimeTable_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } -#endif - break; - - case TABLESOURCE_FUNCTION: { - int colWise; - int dim[MAX_TABLE_DIMENSIONS]; - if (usertab((char*)tableName, 0 /* Time-interpolation */, dim, - &colWise, &tableID->table) == 0) { - if (0 == colWise) { - tableID->nRow = (size_t)dim[0]; - tableID->nCol = (size_t)dim[1]; - } - else { - /* Need to transpose */ - double* tableT = (double*)malloc( - (size_t)dim[0]*(size_t)dim[1]*sizeof(double)); - if (NULL != tableT) { - memcpy(tableT, tableID->table, - (size_t)dim[0]*(size_t)dim[1]*sizeof(double)); - tableID->table = tableT; - tableID->nRow = (size_t)dim[1]; - tableID->nCol = (size_t)dim[0]; - tableID->source = TABLESOURCE_FUNCTION_TRANSPOSE; - transpose(tableID->table, tableID->nRow, tableID->nCol); - } - else { - ModelicaStandardTables_CombiTimeTable_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } - } - } - break; - } - - case TABLESOURCE_FUNCTION_TRANSPOSE: - /* Should not be possible to get here */ - break; - - default: - ModelicaStandardTables_CombiTimeTable_close(tableID); - ModelicaError("Table source error\n"); - return NULL; - } - - if (nCols > 0) { - tableID->cols = (int*)malloc(tableID->nCols*sizeof(int)); - if (NULL != tableID->cols) { - memcpy(tableID->cols, columns, tableID->nCols*sizeof(int)); - } - else { - ModelicaStandardTables_CombiTimeTable_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } - } - - if (isValidCombiTimeTable(tableID, tableName, DO_CLEANUP) == 0) { - return NULL; - } - - if (tableID->nRow <= 2) { - if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - tableID->smoothness = LINEAR_SEGMENTS; - } - } - /* Initialization of the cubic Hermite spline coefficients */ - if (tableID->smoothness == AKIMA_C1) { - tableID->spline = akimaSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == MAKIMA_C1) { - tableID->spline = makimaSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1) { - tableID->spline = fritschButlandSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == STEFFEN_MONOTONE_C1) { - tableID->spline = steffenSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - if (NULL == tableID->spline) { - ModelicaStandardTables_CombiTimeTable_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } - } - - return (void*)tableID; -} - -void ModelicaStandardTables_CombiTimeTable_close(void* _tableID) { - CombiTimeTable* tableID = (CombiTimeTable*)_tableID; - if (NULL == tableID) { - return; - } - if (NULL != tableID->table && tableID->source == TABLESOURCE_FILE) { -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - if (NULL != tableID->key) { - TableShare* file; - MUTEX_LOCK(); - HASH_FIND_STR(tableShare, tableID->key, file); - if (NULL != file) { - /* Share hit */ - if (--file->refCount == 0) { - ModelicaIO_freeRealTable(file->table); - free(file->key); - HASH_DEL(tableShare, file); - free(file); - } - } - MUTEX_UNLOCK(); - } - else { - /* Should not be possible to get here */ - free(tableID->table); - } -#else - if (NULL != tableID->key) { - free(tableID->key); - } - free(tableID->table); -#endif - } - else if (NULL != tableID->table && ( -#if !defined(NO_TABLE_COPY) - tableID->source == TABLESOURCE_MODEL || -#endif - tableID->source == TABLESOURCE_FUNCTION_TRANSPOSE)) { - free(tableID->table); - } - if (tableID->nCols > 0 && NULL != tableID->cols) { - free(tableID->cols); - } - if (NULL != tableID->intervals) { - free(tableID->intervals); - } - spline1DClose(&tableID->spline); - free(tableID); -} - -double ModelicaStandardTables_CombiTimeTable_getValue(void* _tableID, int iCol, - double t, double nextTimeEvent, - double preNextTimeEvent) { - double y = 0.; - CombiTimeTable* tableID = (CombiTimeTable*)_tableID; - if (NULL != tableID && NULL != tableID->table && NULL != tableID->cols && - t >= tableID->startTime) { - if (nextTimeEvent < DBL_MAX && nextTimeEvent == preNextTimeEvent && - tableID->startTime >= nextTimeEvent) { - /* Before start time event iteration: Return zero */ - return y; - } - else { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const size_t col = (size_t)tableID->cols[iCol - 1] - 1; - - if (nRow == 1) { - /* Single row */ - y = TABLE_ROW0(col); - } - else { - enum PointInterval extrapolate = IN_TABLE; - const double tMin = TABLE_ROW0(0); - const double tMax = TABLE_COL0(nRow - 1); - size_t last; - /* Shift time */ - const double tOld = t; - t -= tableID->shiftTime; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = tMax - tMin; - /* Event handling for periodic extrapolation */ - if (nextTimeEvent == preNextTimeEvent && - tOld >= nextTimeEvent) { - /* Before event iteration: Return previous - interval value */ - size_t i; - if (tableID->smoothness == CONSTANT_SEGMENTS) { - i = tableID->intervals[ - tableID->eventInterval - 1][0]; - } - else { - i = tableID->intervals[ - tableID->eventInterval - 1][1]; - } - y = TABLE(i, col); - return y; - } - else if (nextTimeEvent > preNextTimeEvent && - tOld >= preNextTimeEvent && - tableID->startTime < preNextTimeEvent) { - /* In regular (= not start time) event iteration: - Return left interval value */ - size_t i = tableID->intervals[ - tableID->eventInterval - 1][0]; - y = TABLE(i, col); - return y; - } - else { - /* After event iteration */ - const size_t i0 = tableID->intervals[ - tableID->eventInterval - 1][0]; - const size_t i1 = tableID->intervals[ - tableID->eventInterval - 1][1]; - - t -= tableID->tOffset; - if (t < tMin) { - do { - t += T; - } while (t < tMin); - } - else if (t > tMax) { - do { - t -= T; - } while (t > tMax); - } - last = findRowIndex(table, nRow, nCol, tableID->last, t); - tableID->last = last; - /* Event interval correction */ - if (last < i0) { - t = TABLE_COL0(i0); - } - if (last >= i1) { - if (tableID->eventInterval == 1) { - t = TABLE_COL0(i0); - } - else { - t = TABLE_COL0(i1); - } - } - } - } - else if (t < tMin) { - extrapolate = LEFT; - } - else if (t >= tMax) { - extrapolate = RIGHT; - /* Event handling for non-periodic extrapolation */ - if (nextTimeEvent == preNextTimeEvent && - nextTimeEvent < DBL_MAX && tOld >= nextTimeEvent) { - /* Before event iteration */ - extrapolate = IN_TABLE; - } - } - - if (extrapolate == IN_TABLE) { - if (tableID->extrapolation == PERIODIC) { - last = findRowIndex(table, nRow, nCol, - tableID->last, t); - } - else { - /* Event handling for non-periodic extrapolation */ - if (nextTimeEvent == preNextTimeEvent && - nextTimeEvent < DBL_MAX && tOld >= nextTimeEvent) { - /* Before event iteration: Return previous - interval value */ - if (tableID->eventInterval == 1) { - last = 0; - } - else if (tableID->smoothness == CONSTANT_SEGMENTS) { - last = tableID->intervals[ - tableID->eventInterval - 2][0]; - } - else if (tableID->smoothness == LINEAR_SEGMENTS) { - last = tableID->intervals[ - tableID->eventInterval - 2][1]; - } - else if (t >= tMax) { - last = nRow - 1; - } - else { - last = findRowIndex(table, nRow, nCol, - tableID->last, t); - tableID->last = last; - } - y = TABLE(last, col); - return y; - } - else { - last = findRowIndex(table, nRow, nCol, - tableID->last, t); - if (tableID->eventInterval > 1) { - const size_t i0 = tableID->intervals[ - tableID->eventInterval - 2][0]; - const size_t i1 = tableID->intervals[ - tableID->eventInterval - 2][1]; - - /* Event interval correction */ - if (last < i0) { - last = i0; - } - if (last >= i1) { - last = i0; - } - } - } - } - tableID->last = last; - - /* Interpolation */ - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double t0 = TABLE_COL0(last); - const double t1 = TABLE_COL0(last + 1); - const double y0 = TABLE(last, col); - const double y1 = TABLE(last + 1, col); - if (isNearlyEqual(t0, t1)) { - y = y1; - } - else { - LINEAR(t, t0, t1, y0, y1); - } - break; - } - - case CONSTANT_SEGMENTS: - if (t >= TABLE_COL0(last + 1)) { - last++; - } - y = TABLE(last, col); - break; - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - t -= TABLE_COL0(last); - y = TABLE(last, col); /* c[3] = y0 */ - y += ((c[0]*t + c[1])*t + c[2])*t; - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - last = (extrapolate == RIGHT) ? nRow - 2 : 0; - switch(tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: { - const double t0 = TABLE_COL0(last); - const double t1 = TABLE_COL0(last + 1); - const double y0 = TABLE(last, col); - const double y1 = TABLE(last + 1, col); - if (isNearlyEqual(t0, t1)) { - y = (extrapolate == RIGHT) ? y1 : y0; - } - else { - LINEAR(t, t0, t1, y0, y1); - } - break; - } - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - if (extrapolate == LEFT) { - LINEAR_SLOPE(TABLE(0, col), c[2], t - tMin); - } - else /* if (extrapolate == RIGHT) */ { - const double v = tMax - TABLE_COL0(nRow - 2); - LINEAR_SLOPE(TABLE(last + 1, col), - (3*c[0]*v + 2*c[1])*v + c[2], t - tMax); - } - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - y = (extrapolate == RIGHT) ? TABLE(nRow - 1, col) : - TABLE_ROW0(col); - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: Time " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", tOld, - (extrapolate == LEFT) ? "greater" : "less", - (extrapolate == LEFT) ? "minimum" : "maximum", - (extrapolate == LEFT) ? "t_min" : "t_max", - (extrapolate == LEFT) ? tMin : tMax); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - } - } - } - return y; -} - -double ModelicaStandardTables_CombiTimeTable_getDerValue(void* _tableID, int iCol, - double t, - double nextTimeEvent, - double preNextTimeEvent, - double der_t) { - double der_y = 0.; - CombiTimeTable* tableID = (CombiTimeTable*)_tableID; - if (NULL != tableID && NULL != tableID->table && NULL != tableID->cols && - t >= tableID->startTime) { - if (nextTimeEvent < DBL_MAX && nextTimeEvent == preNextTimeEvent && - tableID->startTime >= nextTimeEvent) { - /* Before start time event iteration: Return zero */ - return der_y; - } - else { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const size_t col = (size_t)tableID->cols[iCol - 1] - 1; - - if (nRow > 1) { - enum PointInterval extrapolate = IN_TABLE; - const double tMin = TABLE_ROW0(0); - const double tMax = TABLE_COL0(nRow - 1); - size_t last = 0; - int haveLast = 0; - /* Shift time */ - const double tOld = t; - t -= tableID->shiftTime; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = tMax - tMin; - /* Event handling for periodic extrapolation */ - if (nextTimeEvent == preNextTimeEvent && - tOld >= nextTimeEvent) { - /* Before event iteration: Return previous - interval value */ - last = tableID->intervals[ - tableID->eventInterval - 1][1] - 1; - haveLast = 1; - } - else if (nextTimeEvent > preNextTimeEvent && - tOld >= preNextTimeEvent && - tableID->startTime < preNextTimeEvent) { - /* In regular (= not start time) event iteration: - Return left interval value */ - last = tableID->intervals[ - tableID->eventInterval - 1][0]; - haveLast = 1; - } - else { - /* After event iteration */ - const size_t i0 = tableID->intervals[ - tableID->eventInterval - 1][0]; - const size_t i1 = tableID->intervals[ - tableID->eventInterval - 1][1]; - - t -= tableID->tOffset; - if (t < tMin) { - do { - t += T; - } while (t < tMin); - } - else if (t > tMax) { - do { - t -= T; - } while (t > tMax); - } - last = findRowIndex( - table, nRow, nCol, tableID->last, t); - tableID->last = last; - /* Event interval correction */ - if (last < i0) { - t = TABLE_COL0(i0); - } - if (last >= i1) { - if (tableID->eventInterval == 1) { - t = TABLE_COL0(i0); - } - else { - t = TABLE_COL0(i1); - } - } - } - } - else if (t < tMin) { - extrapolate = LEFT; - } - else if (t >= tMax) { - extrapolate = RIGHT; - /* Event handling for non-periodic extrapolation */ - if (nextTimeEvent == preNextTimeEvent && - nextTimeEvent < DBL_MAX && tOld >= nextTimeEvent) { - /* Before event iteration */ - extrapolate = IN_TABLE; - } - } - - if (extrapolate == IN_TABLE) { - if (tableID->extrapolation != PERIODIC) { - /* Event handling for non-periodic extrapolation */ - if (nextTimeEvent == preNextTimeEvent && - nextTimeEvent < DBL_MAX && tOld >= nextTimeEvent) { - /* Before event iteration */ - if (tableID->eventInterval == 1) { - last = 0; - extrapolate = LEFT; - } - else if (tableID->smoothness == CONSTANT_SEGMENTS) { - last = tableID->intervals[ - tableID->eventInterval - 2][0]; - } - else if (tableID->smoothness == LINEAR_SEGMENTS) { - last = tableID->intervals[ - tableID->eventInterval - 2][1]; - } - else if (t >= tMax) { - last = nRow - 1; - } - else { - last = findRowIndex(table, nRow, nCol, - tableID->last, t); - tableID->last = last; - } - if (last > 0 && extrapolate == IN_TABLE) { - last--; - } - haveLast = 1; - } - } - - if (!haveLast) { - last = findRowIndex(table, nRow, nCol, tableID->last, t); - tableID->last = last; - } - - if (tableID->extrapolation != PERIODIC && - tableID->eventInterval > 1) { - const size_t i0 = tableID->intervals[ - tableID->eventInterval - 2][0]; - const size_t i1 = tableID->intervals[ - tableID->eventInterval - 2][1]; - - if (last < i0) { - last = i0; - } - if (last >= i1) { - last = i0; - } - } - } - - if (extrapolate == IN_TABLE) { - /* Interpolation */ - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double t0 = TABLE_COL0(last); - const double t1 = TABLE_COL0(last + 1); - if (!isNearlyEqual(t0, t1)) { - der_y = (TABLE(last + 1, col) - TABLE(last, col))/ - (t1 - t0); - der_y *= der_t; - } - break; - } - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - t -= TABLE_COL0(last); - der_y = (3*c[0]*t + 2*c[1])*t + c[2]; - der_y *= der_t; - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - last = (extrapolate == RIGHT) ? nRow - 2 : 0; - switch(tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: { - const double t0 = TABLE_COL0(last); - const double t1 = TABLE_COL0(last + 1); - if (!isNearlyEqual(t0, t1)) { - der_y = (TABLE(last + 1, col) - TABLE(last, col))/ - (t1 - t0); - } - break; - } - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - if (extrapolate == LEFT) { - der_y = c[2]; - } - else /* if (extrapolate == RIGHT) */ { - der_y = tMax - TABLE_COL0(nRow - 2); - der_y = (3*c[0]*der_y + 2*c[1])* - der_y + c[2]; - } - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - der_y *= der_t; - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: Time " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", tOld, - (extrapolate == LEFT) ? "greater" : "less", - (extrapolate == LEFT) ? "minimum" : "maximum", - (extrapolate == LEFT) ? "t_min" : "t_max", - (extrapolate == LEFT) ? tMin : tMax); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - } - } - } - return der_y; -} - -double ModelicaStandardTables_CombiTimeTable_getDer2Value(void* _tableID, int iCol, - double t, - double nextTimeEvent, - double preNextTimeEvent, - double der_t, - double der2_t) { - double der2_y = 0.; - CombiTimeTable* tableID = (CombiTimeTable*)_tableID; - if (NULL != tableID && NULL != tableID->table && NULL != tableID->cols && - t >= tableID->startTime) { - if (nextTimeEvent < DBL_MAX && nextTimeEvent == preNextTimeEvent && - tableID->startTime >= nextTimeEvent) { - /* Before start time event iteration: Return zero */ - return der2_y; - } - else { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const size_t col = (size_t)tableID->cols[iCol - 1] - 1; - - if (nRow > 1) { - enum PointInterval extrapolate = IN_TABLE; - const double tMin = TABLE_ROW0(0); - const double tMax = TABLE_COL0(nRow - 1); - size_t last = 0; - int haveLast = 0; - /* Shift time */ - const double tOld = t; - t -= tableID->shiftTime; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = tMax - tMin; - /* Event handling for periodic extrapolation */ - if (nextTimeEvent == preNextTimeEvent && - tOld >= nextTimeEvent) { - /* Before event iteration: Return previous - interval value */ - last = tableID->intervals[ - tableID->eventInterval - 1][1] - 1; - haveLast = 1; - } - else if (nextTimeEvent > preNextTimeEvent && - tOld >= preNextTimeEvent && - tableID->startTime < preNextTimeEvent) { - /* In regular (= not start time) event iteration: - Return left interval value */ - last = tableID->intervals[ - tableID->eventInterval - 1][0]; - haveLast = 1; - } - else { - /* After event iteration */ - const size_t i0 = tableID->intervals[ - tableID->eventInterval - 1][0]; - const size_t i1 = tableID->intervals[ - tableID->eventInterval - 1][1]; - - t -= tableID->tOffset; - if (t < tMin) { - do { - t += T; - } while (t < tMin); - } - else if (t > tMax) { - do { - t -= T; - } while (t > tMax); - } - last = findRowIndex( - table, nRow, nCol, tableID->last, t); - tableID->last = last; - /* Event interval correction */ - if (last < i0) { - t = TABLE_COL0(i0); - } - if (last >= i1) { - if (tableID->eventInterval == 1) { - t = TABLE_COL0(i0); - } - else { - t = TABLE_COL0(i1); - } - } - } - } - else if (t < tMin) { - extrapolate = LEFT; - } - else if (t >= tMax) { - extrapolate = RIGHT; - /* Event handling for non-periodic extrapolation */ - if (nextTimeEvent == preNextTimeEvent && - nextTimeEvent < DBL_MAX && tOld >= nextTimeEvent) { - /* Before event iteration */ - extrapolate = IN_TABLE; - } - } - - if (extrapolate == IN_TABLE) { - if (tableID->extrapolation != PERIODIC) { - /* Event handling for non-periodic extrapolation */ - if (nextTimeEvent == preNextTimeEvent && - nextTimeEvent < DBL_MAX && tOld >= nextTimeEvent) { - /* Before event iteration */ - if (tableID->eventInterval == 1) { - last = 0; - extrapolate = LEFT; - } - else if (tableID->smoothness == CONSTANT_SEGMENTS) { - last = tableID->intervals[ - tableID->eventInterval - 2][0]; - } - else if (tableID->smoothness == LINEAR_SEGMENTS) { - last = tableID->intervals[ - tableID->eventInterval - 2][1]; - } - else if (t >= tMax) { - last = nRow - 1; - } - else { - last = findRowIndex(table, nRow, nCol, - tableID->last, t); - tableID->last = last; - } - if (last > 0 && extrapolate == IN_TABLE) { - last--; - } - haveLast = 1; - } - } - - if (!haveLast) { - last = findRowIndex(table, nRow, nCol, tableID->last, t); - tableID->last = last; - } - - if (tableID->extrapolation != PERIODIC && - tableID->eventInterval > 1) { - const size_t i0 = tableID->intervals[ - tableID->eventInterval - 2][0]; - const size_t i1 = tableID->intervals[ - tableID->eventInterval - 2][1]; - - if (last < i0) { - last = i0; - } - if (last >= i1) { - last = i0; - } - } - } - - if (extrapolate == IN_TABLE) { - /* Interpolation */ - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double t0 = TABLE_COL0(last); - const double t1 = TABLE_COL0(last + 1); - if (!isNearlyEqual(t0, t1)) { - der2_y = (TABLE(last + 1, col) - TABLE(last, col))/ - (t1 - t0); - der2_y *= der2_t; - } - break; - } - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - t -= TABLE_COL0(last); - der2_y = (3*c[0]*t + 2*c[1])*t + c[2]; - der2_y *= der2_t; - der2_y += (6*c[0]*t + 2*c[1])*der_t*der_t; - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - last = (extrapolate == RIGHT) ? nRow - 2 : 0; - switch(tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: { - const double t0 = TABLE_COL0(last); - const double t1 = TABLE_COL0(last + 1); - if (!isNearlyEqual(t0, t1)) { - der2_y = (TABLE(last + 1, col) - TABLE(last, col))/ - (t1 - t0); - } - break; - } - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - if (extrapolate == LEFT) { - der2_y = c[2]; - } - else /* if (extrapolate == RIGHT) */ { - der2_y = tMax - TABLE_COL0(nRow - 2); - der2_y = (3*c[0]*der2_y + 2*c[1])* - der2_y + c[2]; - } - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - der2_y *= der2_t; - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: Time " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", tOld, - (extrapolate == LEFT) ? "greater" : "less", - (extrapolate == LEFT) ? "minimum" : "maximum", - (extrapolate == LEFT) ? "t_min" : "t_max", - (extrapolate == LEFT) ? tMin : tMax); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - } - } - } - return der2_y; -} - -double ModelicaStandardTables_CombiTimeTable_minimumTime(void* _tableID) { - double tMin = 0.; - CombiTimeTable* tableID = (CombiTimeTable*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - tMin = TABLE_ROW0(0); - } - return tMin; -} - -double ModelicaStandardTables_CombiTimeTable_maximumTime(void* _tableID) { - double tMax = 0.; - CombiTimeTable* tableID = (CombiTimeTable*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - const size_t nCol = tableID->nCol; - tMax = TABLE_COL0(tableID->nRow - 1); - } - return tMax; -} - -double ModelicaStandardTables_CombiTimeTable_nextTimeEvent(void* _tableID, - double t) { - double nextTimeEvent = DBL_MAX; - CombiTimeTable* tableID = (CombiTimeTable*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - - if (tableID->nEvent > 0) { - if (t > tableID->preNextTimeEventCalled) { - /* Intentionally empty */ - } - else if (t < tableID->preNextTimeEventCalled) { - /* Force reinitialization of event interval */ - tableID->eventInterval = 0; - /* Reset time event counter */ - tableID->nEvent = 0; - /* Reset time event */ - tableID->preNextTimeEvent = -DBL_MAX; - } - else { - return tableID->preNextTimeEvent; - } - } - else { - /* Determine maximum number of time events (per period) */ - double tEvent = TABLE_ROW0(0); - const double tMax = TABLE_COL0(nRow - 1); - size_t i, eventInterval; - - /* There is at least one time event at the interval boundaries */ - tableID->maxEvents = 1; - if (tableID->timeEvents == ALWAYS || - tableID->timeEvents == AT_DISCONT) { - for (i = 0; i < nRow - 1; i++) { - double t0 = TABLE_COL0(i); - double t1 = TABLE_COL0(i + 1); - if (t1 > tEvent && !isNearlyEqual(t1, tMax)) { - int isEq = isNearlyEqual(t0, t1); - if ((tableID->timeEvents == ALWAYS && !isEq) || - (tableID->timeEvents == AT_DISCONT && isEq)) { - tEvent = t1; - tableID->maxEvents++; - } - } - } - } - /* Once again with storage of indices of event intervals */ - tableID->intervals = (Interval*)calloc(tableID->maxEvents, - sizeof(Interval)); - if (NULL == tableID->intervals) { - ModelicaError("Memory allocation error\n"); - return nextTimeEvent; - } - - tEvent = TABLE_ROW0(0); - eventInterval = 0; - if (tableID->timeEvents == ALWAYS || - tableID->timeEvents == AT_DISCONT) { - for (i = 0; i < nRow - 1 && - eventInterval < tableID->maxEvents; i++) { - double t0 = TABLE_COL0(i); - double t1 = TABLE_COL0(i + 1); - if (tableID->timeEvents == ALWAYS) { - if (t1 > tEvent) { - if (!isNearlyEqual(t0, t1)) { - tEvent = t1; - tableID->intervals[eventInterval][0] = i; - tableID->intervals[eventInterval][1] = i + 1; - eventInterval++; - } - else { - tableID->intervals[eventInterval][0] = i + 1; - } - } - else { - tableID->intervals[eventInterval][1] = i + 1; - } - } - else /* if (tableID->timeEvents == AT_DISCONT) */ { - if (t1 > tEvent) { - if (isNearlyEqual(t0, t1)) { - tEvent = t1; - tableID->intervals[eventInterval][1] = i; - eventInterval++; - if (eventInterval < tableID->maxEvents) { - tableID->intervals[eventInterval][0] = i + 1; - } - } - else { - tableID->intervals[eventInterval][1] = i + 1; - } - } - else { - tableID->intervals[eventInterval][0] = i + 1; - } - } - } - } - else { - tableID->intervals[0][1] = nRow - 1; - } - } - - tableID->preNextTimeEventCalled = t; - if (t < tableID->startTime) { - nextTimeEvent = tableID->startTime; - } - else if (nRow > 1) { - const double tMin = TABLE_ROW0(0); - const double tMax = TABLE_COL0(nRow - 1); - const double T = tMax - tMin; - if (tableID->eventInterval == 0) { - /* Initialization of event interval */ -#if defined(DEBUG_TIME_EVENTS) - const double tOld = t; -#endif - double tEvent = tMin; - size_t iStart, iEnd; - - t -= tableID->shiftTime; - if (tableID->extrapolation == PERIODIC) { - /* Initialization of offset time */ - tableID->tOffset = floor((t - tMin)/T)*T; - t -= tableID->tOffset; - if (t < tMin) { - t += T; - } - else if (t > tMax) { - t -= T; - } - iStart = findRowIndex(table, nRow, nCol, tableID->last, - t + _EPSILON*T); - nextTimeEvent = tMax; - tableID->eventInterval = 1; - iEnd = iStart < (nRow - 1) ? iStart : (nRow - 1); - } - else if (t >= tMax) { - iStart = nRow - 1; - tableID->eventInterval = tableID->maxEvents + 1; - iEnd = 0; - } - else if (t < tMin) { - iStart = nRow - 1; - nextTimeEvent = tMin; - tableID->eventInterval = 1; - iEnd = 0; - } - else if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - iStart = nRow - 1; - nextTimeEvent = tMax; - iEnd = 0; - } - else { - iStart = findRowIndex(table, nRow, nCol, tableID->last, - t + _EPSILON*T); - nextTimeEvent = tMax; - tableID->eventInterval = 2; - iEnd = iStart < (nRow - 1) ? iStart : (nRow - 1); - } - - if (tableID->timeEvents == ALWAYS || - tableID->timeEvents == AT_DISCONT) { - size_t i; - for (i = iStart + 1; i < nRow - 1; i++) { - double t0 = TABLE_COL0(i); - if (t0 > t) { - double t1 = TABLE_COL0(i + 1); - int isEq = isNearlyEqual(t0, t1); - if ((tableID->timeEvents == ALWAYS && !isEq) || - (tableID->timeEvents == AT_DISCONT && isEq)) { - nextTimeEvent = t0; - break; - } - } - } - - for (i = 0; i < iEnd; i++) { - double t0 = TABLE_COL0(i); - double t1 = TABLE_COL0(i + 1); - if (t1 > tEvent && !isNearlyEqual(t1, tMax)) { - int isEq = isNearlyEqual(t0, t1); - if ((tableID->timeEvents == ALWAYS && !isEq) || - (tableID->timeEvents == AT_DISCONT && isEq)) { - tEvent = t1; - tableID->eventInterval++; - } - } - } - } - - if (tableID->extrapolation == PERIODIC) { - nextTimeEvent += tableID->tOffset; - if (tableID->eventInterval == tableID->maxEvents) { - tableID->tOffset += T; - } - } -#if defined(DEBUG_TIME_EVENTS) - t = tOld; -#endif - if (nextTimeEvent < DBL_MAX) { - nextTimeEvent += tableID->shiftTime; - } - } - else { - do { - if (tableID->extrapolation == PERIODIC) { - /* Increment event interval */ - tableID->eventInterval = - 1 + tableID->eventInterval % tableID->maxEvents; - if (tableID->eventInterval == tableID->maxEvents) { - nextTimeEvent = tMax + tableID->tOffset + - tableID->shiftTime; - tableID->tOffset += T; - } - else { - size_t i = tableID->intervals[ - tableID->eventInterval - 1][1]; - nextTimeEvent = TABLE_COL0(i) + tableID->tOffset + - tableID->shiftTime; - } - } - else if (tableID->eventInterval <= tableID->maxEvents) { - size_t i = tableID->intervals[ - tableID->eventInterval - 1][1]; - nextTimeEvent = TABLE_COL0(i) + tableID->shiftTime; - /* Increment event interval */ - tableID->eventInterval++; - } - else { - nextTimeEvent = DBL_MAX; - } - } while (nextTimeEvent <= t); - } - } - - if (nextTimeEvent > tableID->preNextTimeEvent) { - tableID->preNextTimeEvent = nextTimeEvent; - tableID->nEvent++; - } - -#if defined(DEBUG_TIME_EVENTS) - if (nextTimeEvent < DBL_MAX) { - if (tableID->extrapolation == PERIODIC) { - ModelicaFormatMessage("At time %.17lg (interval %lu of %lu): %lu. " - "time event at %.17lg\n", t, (unsigned long)tableID->eventInterval, - (unsigned long)tableID->maxEvents, (unsigned long)tableID->nEvent, - nextTimeEvent); - } - else if (tableID->eventInterval > 0) { - ModelicaFormatMessage("At time %.17lg (interval %lu of %lu): %lu. " - "time event at %.17lg\n", t, (unsigned long)tableID->eventInterval - 1, - (unsigned long)tableID->maxEvents, (unsigned long)tableID->nEvent, - nextTimeEvent); - } - else { - ModelicaFormatMessage("At time %.17lg: %lu. " - "time event at %.17lg\n", t, (unsigned long)tableID->nEvent, - nextTimeEvent); - } - } - else { - ModelicaFormatMessage("No more time events for time > %.17lg\n", t); - } -#endif - } - else { - /* Should not be possible to get here */ - ModelicaError( - "No table data available for detection of time events\n"); - return nextTimeEvent; - } - - return nextTimeEvent; -} - -double ModelicaStandardTables_CombiTimeTable_read(void* _tableID, int force, - int verbose) { -#if !defined(NO_FILE_SYSTEM) - CombiTimeTable* tableID = (CombiTimeTable*)_tableID; - if (NULL != tableID && tableID->source == TABLESOURCE_FILE) { - if (force || NULL == tableID->table) { - const char* fileName = tableID->key; - const char* tableName = tableID->key + strlen(fileName) + 1; -#if defined(TABLE_SHARE) - TableShare* file = readTable(fileName, tableName, &tableID->nRow, - &tableID->nCol, verbose, force, ",", 0); - if (NULL != file) { - tableID->table = file->table; - } - else { - return 0.; /* Error */ - } -#else - if (NULL != tableID->table) { - free(tableID->table); - } - tableID->table = readTable(fileName, tableName, &tableID->nRow, - &tableID->nCol, verbose, force, ",", 0); -#endif - if (NULL == tableID->table) { - return 0.; /* Error */ - } - if (isValidCombiTimeTable(tableID, tableName, NO_CLEANUP) == 0) { - return 0.; /* Error */ - } - if (tableID->nRow <= 2) { - if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - tableID->smoothness = LINEAR_SEGMENTS; - } - } - /* Reinitialization of the cubic Hermite spline coefficients */ - if (tableID->smoothness == AKIMA_C1) { - spline1DClose(&tableID->spline); - tableID->spline = akimaSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == MAKIMA_C1) { - spline1DClose(&tableID->spline); - tableID->spline = makimaSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1) { - spline1DClose(&tableID->spline); - tableID->spline = fritschButlandSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == STEFFEN_MONOTONE_C1) { - spline1DClose(&tableID->spline); - tableID->spline = steffenSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - if (NULL == tableID->spline) { - ModelicaError("Memory allocation error\n"); - return 0.; /* Error */ - } - } - } - } -#endif - return 1.; /* Success */ -} - -void* ModelicaStandardTables_CombiTable1D_init(_In_z_ const char* tableName, - _In_z_ const char* fileName, - _In_ double* table, size_t nRow, - size_t nColumn, - _In_ int* columns, - size_t nCols, int smoothness) { - return ModelicaStandardTables_CombiTable1D_init2(fileName, tableName, - table, nRow, nColumn, columns, nCols, smoothness, LAST_TWO_POINTS, - 1 /* verbose */); -} - -void* ModelicaStandardTables_CombiTable1D_init2(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation, - int verbose) { - return ModelicaStandardTables_CombiTable1D_init3(fileName, tableName, - table, nRow, nColumn, columns, nCols, smoothness, extrapolation, - verbose, ",", 0); -} - -void* ModelicaStandardTables_CombiTable1D_init3(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation, - int verbose, - _In_z_ const char* delimiter, - int nHeaderLines) { - CombiTable1D* tableID; -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - TableShare* file = NULL; - char* keyFile = NULL; -#endif - double* tableFile = NULL; - size_t nRowFile = 0; - size_t nColFile = 0; - enum TableSource source = getTableSource(fileName, tableName); - - /* Read table from file before any other heap allocation */ - if (TABLESOURCE_FILE == source) { -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - file = readTable(fileName, tableName, &nRowFile, &nColFile, verbose, 0, delimiter, nHeaderLines); - if (NULL != file) { - keyFile = file->key; - tableFile = file->table; - } - else { - return NULL; - } -#else - tableFile = readTable(fileName, tableName, &nRowFile, &nColFile, verbose, 0, delimiter, nHeaderLines); - if (NULL == tableFile) { - return NULL; - } -#endif - } - - tableID = (CombiTable1D*)calloc(1, sizeof(CombiTable1D)); - if (NULL == tableID) { -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - if (NULL != file) { - MUTEX_LOCK(); - if (--file->refCount == 0) { - ModelicaIO_freeRealTable(file->table); - free(file->key); - HASH_DEL(tableShare, file); - free(file); - } - MUTEX_UNLOCK(); - } -#else - if (NULL != tableFile) { - free(tableFile); - } -#endif - ModelicaError("Memory allocation error\n"); - return NULL; - } - - tableID->smoothness = (enum Smoothness)smoothness; - tableID->extrapolation = (enum Extrapolation)extrapolation; - tableID->nCols = nCols; - tableID->source = source; - - switch (tableID->source) { - case TABLESOURCE_FILE: -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - tableID->key = keyFile; -#else - { - size_t lenFileName = strlen(fileName); - tableID->key = (char*)malloc((lenFileName + strlen(tableName) + 2)*sizeof(char)); - if (NULL != tableID->key) { - strcpy(tableID->key, fileName); - strcpy(tableID->key + lenFileName + 1, tableName); - } - } -#endif - tableID->nRow = nRowFile; - tableID->nCol = nColFile; - tableID->table = tableFile; - break; - - case TABLESOURCE_MODEL: - tableID->nRow = nRow; - tableID->nCol = nColumn; -#if defined(NO_TABLE_COPY) - tableID->table = table; -#else - tableID->table = (double*)malloc(nRow*nColumn*sizeof(double)); - if (NULL != tableID->table) { - memcpy(tableID->table, table, nRow*nColumn*sizeof(double)); - } - else { - ModelicaStandardTables_CombiTable1D_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } -#endif - break; - - case TABLESOURCE_FUNCTION: { - int colWise; - int dim[MAX_TABLE_DIMENSIONS]; - if (usertab((char*)tableName, 1 /* 1D-interpolation */, dim, - &colWise, &tableID->table) == 0) { - if (0 == colWise) { - tableID->nRow = (size_t)dim[0]; - tableID->nCol = (size_t)dim[1]; - } - else { - /* Need to transpose */ - double* tableT = (double*)malloc( - (size_t)dim[0]*(size_t)dim[1]*sizeof(double)); - if (NULL != tableT) { - memcpy(tableT, tableID->table, - (size_t)dim[0]*(size_t)dim[1]*sizeof(double)); - tableID->table = tableT; - tableID->nRow = (size_t)dim[1]; - tableID->nCol = (size_t)dim[0]; - tableID->source = TABLESOURCE_FUNCTION_TRANSPOSE; - transpose(tableID->table, tableID->nRow, tableID->nCol); - } - else { - ModelicaStandardTables_CombiTable1D_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } - } - } - break; - } - - case TABLESOURCE_FUNCTION_TRANSPOSE: - /* Should not be possible to get here */ - break; - - default: - ModelicaStandardTables_CombiTable1D_close(tableID); - ModelicaError("Table source error\n"); - return NULL; - } - - if (nCols > 0) { - tableID->cols = (int*)malloc(tableID->nCols*sizeof(int)); - if (NULL != tableID->cols) { - memcpy(tableID->cols, columns, tableID->nCols*sizeof(int)); - } - else { - ModelicaStandardTables_CombiTable1D_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } - } - - if (isValidCombiTable1D(tableID, tableName, DO_CLEANUP) == 0) { - return NULL; - } - - if (tableID->nRow <= 2) { - if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - tableID->smoothness = LINEAR_SEGMENTS; - } - } - /* Initialization of the cubic Hermite spline coefficients */ - if (tableID->smoothness == AKIMA_C1) { - tableID->spline = akimaSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == MAKIMA_C1) { - tableID->spline = makimaSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1) { - tableID->spline = fritschButlandSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == STEFFEN_MONOTONE_C1) { - tableID->spline = steffenSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - if (NULL == tableID->spline) { - ModelicaStandardTables_CombiTable1D_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } - } - - return (void*)tableID; -} - -void ModelicaStandardTables_CombiTable1D_close(void* _tableID) { - CombiTable1D* tableID = (CombiTable1D*)_tableID; - if (NULL == tableID) { - return; - } - if (NULL != tableID->table && tableID->source == TABLESOURCE_FILE) { -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - if (NULL != tableID->key) { - TableShare* file; - MUTEX_LOCK(); - HASH_FIND_STR(tableShare, tableID->key, file); - if (NULL != file) { - /* Share hit */ - if (--file->refCount == 0) { - ModelicaIO_freeRealTable(file->table); - free(file->key); - HASH_DEL(tableShare, file); - free(file); - } - } - MUTEX_UNLOCK(); - } - else { - /* Should not be possible to get here */ - free(tableID->table); - } -#else - if (NULL != tableID->key) { - free(tableID->key); - } - free(tableID->table); -#endif - } - else if (NULL != tableID->table && ( -#if !defined(NO_TABLE_COPY) - tableID->source == TABLESOURCE_MODEL || -#endif - tableID->source == TABLESOURCE_FUNCTION_TRANSPOSE)) { - free(tableID->table); - } - if (tableID->nCols > 0 && NULL != tableID->cols) { - free(tableID->cols); - } - spline1DClose(&tableID->spline); - free(tableID); -} - -double ModelicaStandardTables_CombiTable1D_getValue(void* _tableID, int iCol, - double u) { - double y = 0.; - CombiTable1D* tableID = (CombiTable1D*)_tableID; - if (NULL != tableID && NULL != tableID->table && NULL != tableID->cols) { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const size_t col = (size_t)tableID->cols[iCol - 1] - 1; - - if (nRow == 1) { - /* Single row */ - y = TABLE_ROW0(col); - } - else { - enum PointInterval extrapolate = IN_TABLE; - const double uMin = TABLE_ROW0(0); - const double uMax = TABLE_COL0(nRow - 1); - size_t last; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = uMax - uMin; - - if (u < uMin) { - do { - u += T; - } while (u < uMin); - } - else if (u > uMax) { - do { - u -= T; - } while (u > uMax); - } - last = findRowIndex(table, nRow, nCol, tableID->last, u); - tableID->last = last; - } - else if (u < uMin) { - extrapolate = LEFT; - last = 0; - } - else if (u > uMax) { - extrapolate = RIGHT; - last = nRow - 2; - } - else { - last = findRowIndex(table, nRow, nCol, tableID->last, u); - tableID->last = last; - } - - if (extrapolate == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double u0 = TABLE_COL0(last); - const double u1 = TABLE_COL0(last + 1); - const double y0 = TABLE(last, col); - const double y1 = TABLE(last + 1, col); - LINEAR(u, u0, u1, y0, y1); - break; - } - - case CONSTANT_SEGMENTS: - if (u >= TABLE_COL0(last + 1)) { - last++; - } - y = TABLE(last, col); - break; - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - const double v = u - TABLE_COL0(last); - y = TABLE(last, col); /* c[3] = y0 */ - y += ((c[0]*v + c[1])*v + c[2])*v; - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: { - const double u0 = TABLE_COL0(last); - const double u1 = TABLE_COL0(last + 1); - const double y0 = TABLE(last, col); - const double y1 = TABLE(last + 1, col); - LINEAR(u, u0, u1, y0, y1); - break; - } - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - if (extrapolate == LEFT) { - LINEAR_SLOPE(TABLE(0, col), c[2], u - uMin); - } - else /* if (extrapolate == RIGHT) */ { - const double v = uMax - TABLE_COL0(nRow - 2); - LINEAR_SLOPE(TABLE(nRow - 1, col), - (3*c[0]*v + 2*c[1])*v + c[2], u - uMax); - } - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - y = (extrapolate == RIGHT) ? TABLE(nRow - 1, col) : - TABLE_ROW0(col); - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", u, - (extrapolate == LEFT) ? "greater" : "less", - (extrapolate == LEFT) ? "minimum" : "maximum", - (extrapolate == LEFT) ? "u_min" : "u_max", - (extrapolate == LEFT) ? uMin : uMax); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - } - } - return y; -} - -double ModelicaStandardTables_CombiTable1D_getDerValue(void* _tableID, int iCol, - double u, double der_u) { - double der_y = 0.; - CombiTable1D* tableID = (CombiTable1D*)_tableID; - if (NULL != tableID && NULL != tableID->table && NULL != tableID->cols) { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const size_t col = (size_t)tableID->cols[iCol - 1] - 1; - - if (nRow > 1) { - enum PointInterval extrapolate = IN_TABLE; - const double uMin = TABLE_ROW0(0); - const double uMax = TABLE_COL0(nRow - 1); - size_t last; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = uMax - uMin; - - if (u < uMin) { - do { - u += T; - } while (u < uMin); - } - else if (u > uMax) { - do { - u -= T; - } while (u > uMax); - } - last = findRowIndex(table, nRow, nCol, tableID->last, u); - tableID->last = last; - } - else if (u < uMin) { - extrapolate = LEFT; - last = 0; - } - else if (u > uMax) { - extrapolate = RIGHT; - last = nRow - 2; - } - else { - last = findRowIndex(table, nRow, nCol, tableID->last, u); - tableID->last = last; - } - - if (extrapolate == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - der_y = (TABLE(last + 1, col) - TABLE(last, col))/ - (TABLE_COL0(last + 1) - TABLE_COL0(last)); - der_y *= der_u; - break; - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - const double v = u - TABLE_COL0(last); - der_y = (3*c[0]*v + 2*c[1])*v + c[2]; - der_y *= der_u; - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: { - const double u0 = TABLE_COL0(last); - const double u1 = TABLE_COL0(last + 1); - der_y = (TABLE(last + 1, col) - TABLE(last, col))/ - (u1 - u0); - break; - } - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - if (extrapolate == LEFT) { - der_y = c[2]; - } - else /* if (extrapolate == RIGHT) */ { - der_y = uMax - TABLE_COL0(nRow - 2); - der_y = (3*c[0]*der_y + 2*c[1])* - der_y + c[2]; - } - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - der_y *= der_u; - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", u, - (extrapolate == LEFT) ? "greater" : "less", - (extrapolate == LEFT) ? "minimum" : "maximum", - (extrapolate == LEFT) ? "u_min" : "u_max", - (extrapolate == LEFT) ? uMin : uMax); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - } - } - return der_y; -} - -double ModelicaStandardTables_CombiTable1D_getDer2Value(void* _tableID, int iCol, - double u, double der_u, - double der2_u) { - double der2_y = 0.; - CombiTable1D* tableID = (CombiTable1D*)_tableID; - if (NULL != tableID && NULL != tableID->table && NULL != tableID->cols) { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const size_t col = (size_t)tableID->cols[iCol - 1] - 1; - - if (nRow > 1) { - enum PointInterval extrapolate = IN_TABLE; - const double uMin = TABLE_ROW0(0); - const double uMax = TABLE_COL0(nRow - 1); - size_t last; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = uMax - uMin; - - if (u < uMin) { - do { - u += T; - } while (u < uMin); - } - else if (u > uMax) { - do { - u -= T; - } while (u > uMax); - } - last = findRowIndex(table, nRow, nCol, tableID->last, u); - tableID->last = last; - } - else if (u < uMin) { - extrapolate = LEFT; - last = 0; - } - else if (u > uMax) { - extrapolate = RIGHT; - last = nRow - 2; - } - else { - last = findRowIndex(table, nRow, nCol, tableID->last, u); - tableID->last = last; - } - - if (extrapolate == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - der2_y = (TABLE(last + 1, col) - TABLE(last, col))/ - (TABLE_COL0(last + 1) - TABLE_COL0(last)); - der2_y *= der2_u; - break; - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - const double v = u - TABLE_COL0(last); - der2_y = (3*c[0]*v + 2*c[1])*v + c[2]; - der2_y *= der2_u; - der2_y += (6*c[0]*v + 2*c[1])*der_u*der_u; - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: { - const double u0 = TABLE_COL0(last); - const double u1 = TABLE_COL0(last + 1); - der2_y = (TABLE(last + 1, col) - TABLE(last, col))/ - (u1 - u0); - break; - } - - case AKIMA_C1: - case MAKIMA_C1: - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last, (size_t)(iCol - 1), tableID->nCols)]; - if (extrapolate == LEFT) { - der2_y = c[2]; - } - else /* if (extrapolate == RIGHT) */ { - der2_y = uMax - TABLE_COL0(nRow - 2); - der2_y = (3*c[0]*der2_y + 2*c[1])* - der2_y + c[2]; - } - } - break; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - der2_y *= der2_u; - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", u, - (extrapolate == LEFT) ? "greater" : "less", - (extrapolate == LEFT) ? "minimum" : "maximum", - (extrapolate == LEFT) ? "u_min" : "u_max", - (extrapolate == LEFT) ? uMin : uMax); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - } - } - return der2_y; -} - -double ModelicaStandardTables_CombiTable1D_minimumAbscissa(void* _tableID) { - double uMin = 0.; - CombiTable1D* tableID = (CombiTable1D*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - uMin = TABLE_ROW0(0); - } - return uMin; -} - -double ModelicaStandardTables_CombiTable1D_maximumAbscissa(void* _tableID) { - double uMax = 0.; - CombiTable1D* tableID = (CombiTable1D*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - const size_t nCol = tableID->nCol; - uMax = TABLE_COL0(tableID->nRow - 1); - } - return uMax; -} - -double ModelicaStandardTables_CombiTable1D_read(void* _tableID, int force, - int verbose) { -#if !defined(NO_FILE_SYSTEM) - CombiTable1D* tableID = (CombiTable1D*)_tableID; - if (NULL != tableID && tableID->source == TABLESOURCE_FILE) { - if (force || NULL == tableID->table) { - const char* fileName = tableID->key; - const char* tableName = tableID->key + strlen(fileName) + 1; -#if defined(TABLE_SHARE) - TableShare* file = readTable(fileName, tableName, &tableID->nRow, - &tableID->nCol, verbose, force, ",", 0); - if (NULL != file) { - tableID->table = file->table; - } - else { - return 0.; /* Error */ - } -#else - if (NULL != tableID->table) { - free(tableID->table); - } - tableID->table = readTable(fileName, tableName, &tableID->nRow, - &tableID->nCol, verbose, force, ",", 0); -#endif - if (NULL == tableID->table) { - return 0.; /* Error */ - } - if (isValidCombiTable1D(tableID, tableName, NO_CLEANUP) == 0) { - return 0.; /* Error */ - } - if (tableID->nRow <= 2) { - if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - tableID->smoothness = LINEAR_SEGMENTS; - } - } - /* Reinitialization of the cubic Hermite spline coefficients */ - if (tableID->smoothness == AKIMA_C1) { - spline1DClose(&tableID->spline); - tableID->spline = akimaSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == MAKIMA_C1) { - spline1DClose(&tableID->spline); - tableID->spline = makimaSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1) { - spline1DClose(&tableID->spline); - tableID->spline = fritschButlandSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - else if (tableID->smoothness == STEFFEN_MONOTONE_C1) { - spline1DClose(&tableID->spline); - tableID->spline = steffenSpline1DInit( - (const double*)tableID->table, tableID->nRow, - tableID->nCol, (const int*)tableID->cols, tableID->nCols); - } - if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - if (NULL == tableID->spline) { - ModelicaError("Memory allocation error\n"); - return 0.; /* Error */ - } - } - } - } -#endif - return 1.; /* Success */ -} - -void* ModelicaStandardTables_CombiTable2D_init(_In_z_ const char* tableName, - _In_z_ const char* fileName, - _In_ double* table, size_t nRow, - size_t nColumn, int smoothness) { - return ModelicaStandardTables_CombiTable2D_init2(fileName, tableName, - table, nRow, nColumn, smoothness, LAST_TWO_POINTS, 1 /* verbose */); -} - -void* ModelicaStandardTables_CombiTable2D_init2(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, int smoothness, - int extrapolation, - int verbose) { - return ModelicaStandardTables_CombiTable2D_init3(fileName, tableName, - table, nRow, nColumn, smoothness, extrapolation, verbose, ",", 0); -} - -void* ModelicaStandardTables_CombiTable2D_init3(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, int smoothness, - int extrapolation, - int verbose, - _In_z_ const char* delimiter, - int nHeaderLines) { - CombiTable2D* tableID; -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - TableShare* file = NULL; - char* keyFile = NULL; -#endif - double* tableFile = NULL; - size_t nRowFile = 0; - size_t nColFile = 0; - enum TableSource source = getTableSource(fileName, tableName); - - /* Read table from file before any other heap allocation */ - if (TABLESOURCE_FILE == source) { -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - file = readTable(fileName, tableName, &nRowFile, &nColFile, verbose, 0, delimiter, nHeaderLines); - if (NULL != file) { - keyFile = file->key; - tableFile = file->table; - } - else { - return NULL; - } -#else - tableFile = readTable(fileName, tableName, &nRowFile, &nColFile, verbose, 0, delimiter, nHeaderLines); - if (NULL == tableFile) { - return NULL; - } -#endif - } - - tableID = (CombiTable2D*)calloc(1, sizeof(CombiTable2D)); - if (NULL == tableID) { -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - if (NULL != file) { - MUTEX_LOCK(); - if (--file->refCount == 0) { - ModelicaIO_freeRealTable(file->table); - free(file->key); - HASH_DEL(tableShare, file); - free(file); - } - MUTEX_UNLOCK(); - } -#else - if (NULL != tableFile) { - free(tableFile); - } -#endif - ModelicaError("Memory allocation error\n"); - return NULL; - } - - tableID->smoothness = (enum Smoothness)smoothness; - tableID->extrapolation = (enum Extrapolation)extrapolation; - tableID->source = source; - - switch (tableID->source) { - case TABLESOURCE_FILE: -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - tableID->key = keyFile; -#else - { - size_t lenFileName = strlen(fileName); - tableID->key = (char*)malloc((lenFileName + strlen(tableName) + 2)*sizeof(char)); - if (NULL != tableID->key) { - strcpy(tableID->key, fileName); - strcpy(tableID->key + lenFileName + 1, tableName); - } - } -#endif - tableID->nRow = nRowFile; - tableID->nCol = nColFile; - tableID->table = tableFile; - break; - - case TABLESOURCE_MODEL: - tableID->nRow = nRow; - tableID->nCol = nColumn; -#if defined(NO_TABLE_COPY) - tableID->table = table; -#else - tableID->table = (double*)malloc(nRow*nColumn*sizeof(double)); - if (NULL != tableID->table) { - memcpy(tableID->table, table, nRow*nColumn*sizeof(double)); - } - else { - ModelicaStandardTables_CombiTable2D_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } -#endif - break; - - case TABLESOURCE_FUNCTION: { - int colWise; - int dim[MAX_TABLE_DIMENSIONS]; - if (usertab((char*)tableName, 2 /* 2D-interpolation */, dim, - &colWise, &tableID->table) == 0) { - if (0 == colWise) { - tableID->nRow = (size_t)dim[0]; - tableID->nCol = (size_t)dim[1]; - } - else { - /* Need to transpose */ - double* tableT = (double*)malloc( - (size_t)dim[0]*(size_t)dim[1]*sizeof(double)); - if (NULL != tableT) { - memcpy(tableT, tableID->table, - (size_t)dim[0]*(size_t)dim[1]*sizeof(double)); - tableID->table = tableT; - tableID->nRow = (size_t)dim[1]; - tableID->nCol = (size_t)dim[0]; - tableID->source = TABLESOURCE_FUNCTION_TRANSPOSE; - transpose(tableID->table, tableID->nRow, tableID->nCol); - } - else { - ModelicaStandardTables_CombiTable2D_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } - } - } - break; - } - - case TABLESOURCE_FUNCTION_TRANSPOSE: - /* Should not be possible to get here */ - break; - - default: - ModelicaStandardTables_CombiTable2D_close(tableID); - ModelicaError("Table source error\n"); - return NULL; - } - - if (isValidCombiTable2D(tableID, tableName, DO_CLEANUP) == 0) { - return NULL; - } - - if (tableID->smoothness == AKIMA_C1 && - tableID->nRow <= 3 && tableID->nCol <= 3) { - tableID->smoothness = LINEAR_SEGMENTS; - } - /* Initialization of the Akima-spline coefficients */ - if (tableID->smoothness == AKIMA_C1) { - tableID->spline = spline2DInit((const double*)tableID->table, - tableID->nRow, tableID->nCol); - if (NULL == tableID->spline) { - ModelicaStandardTables_CombiTable2D_close(tableID); - ModelicaError("Memory allocation error\n"); - return NULL; - } - } - - return (void*)tableID; -} - -void ModelicaStandardTables_CombiTable2D_close(void* _tableID) { - CombiTable2D* tableID = (CombiTable2D*)_tableID; - if (NULL == tableID) { - return; - } - if (NULL != tableID->table && tableID->source == TABLESOURCE_FILE) { -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) - if (NULL != tableID->key) { - TableShare* file; - MUTEX_LOCK(); - HASH_FIND_STR(tableShare, tableID->key, file); - if (NULL != file) { - /* Share hit */ - if (--file->refCount == 0) { - ModelicaIO_freeRealTable(file->table); - free(file->key); - HASH_DEL(tableShare, file); - free(file); - } - } - MUTEX_UNLOCK(); - } - else { - /* Should not be possible to get here */ - free(tableID->table); - } -#else - if (NULL != tableID->key) { - free(tableID->key); - } - free(tableID->table); -#endif - } - else if (NULL != tableID->table && ( -#if !defined(NO_TABLE_COPY) - tableID->source == TABLESOURCE_MODEL || -#endif - tableID->source == TABLESOURCE_FUNCTION_TRANSPOSE)) { - free(tableID->table); - } - spline2DClose(&tableID->spline); - free(tableID); -} - -double ModelicaStandardTables_CombiTable2D_getValue(void* _tableID, double u1, - double u2) { - double y = 0; - CombiTable2D* tableID = (CombiTable2D*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const double u1Min = TABLE_COL0(1); - const double u1Max = TABLE_COL0(nRow - 1); - const double u2Min = TABLE_ROW0(1); - const double u2Max = TABLE_ROW0(nCol - 1); - - if (nRow == 2) { - if (nCol == 2) { - /* Single row */ - y = TABLE(1, 1); - } - else if (nCol > 2) { - enum PointInterval extrapolate2 = IN_TABLE; - size_t last2; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = u2Max - u2Min; - - if (u2 < u2Min) { - do { - u2 += T; - } while (u2 < u2Min); - } - else if (u2 > u2Max) { - do { - u2 -= T; - } while (u2 > u2Max); - } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - else if (u2 < u2Min) { - extrapolate2 = LEFT; - last2 = 0; - } - else if (u2 > u2Max) { - extrapolate2 = RIGHT; - last2 = nCol - 3; - } - else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - - if (extrapolate2 == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double u20 = TABLE_ROW0(last2 + 1); - const double u21 = TABLE_ROW0(last2 + 2); - const double y0 = TABLE(1, last2 + 1); - const double y1 = TABLE(1, last2 + 2); - LINEAR(u2, u20, u21, y0, y1); - break; - } - - case CONSTANT_SEGMENTS: - if (u2 >= TABLE_ROW0(last2 + 2)) { - last2++; - } - y = TABLE(1, last2 + 1); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last2]; - const double v = u2 - TABLE_ROW0(last2 + 1); - y = TABLE(1, last2 + 1); /* c[3] = y0 */ - y += ((c[0]*v + c[1])*v + c[2])*v; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: { - const double u20 = TABLE_ROW0(last2 + 1); - const double u21 = TABLE_ROW0(last2 + 2); - const double y0 = TABLE(1, last2 + 1); - const double y1 = TABLE(1, last2 + 2); - LINEAR(u2, u20, u21, y0, y1); - break; - } - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last2]; - if (extrapolate2 == LEFT) { - LINEAR_SLOPE(TABLE(1, 1), c[2], u2 - u2Min); - } - else /* if (extrapolate2 == RIGHT) */ { - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - LINEAR_SLOPE(TABLE(1, nCol - 1), (3*c[0]*v2 + - 2*c[1])*v2 + c[2], u2 - u2Max); - } - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - y = (extrapolate2 == RIGHT) ? TABLE(1, nCol - 1) : - TABLE(1, 1); - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u2 " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", u2, - (extrapolate2 == LEFT) ? "greater" : "less", - (extrapolate2 == LEFT) ? "minimum" : "maximum", - (extrapolate2 == LEFT) ? "u_min[2]" : "u_max[2]", - (extrapolate2 == LEFT) ? u2Min : u2Max); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - } - } - else if (nRow > 2) { - enum PointInterval extrapolate1 = IN_TABLE; - size_t last1; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = u1Max - u1Min; - - if (u1 < u1Min) { - do { - u1 += T; - } while (u1 < u1Min); - } - else if (u1 > u1Max) { - do { - u1 -= T; - } while (u1 > u1Max); - } - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); - tableID->last1 = last1; - } - else if (u1 < u1Min) { - extrapolate1 = LEFT; - last1 = 0; - } - else if (u1 > u1Max) { - extrapolate1 = RIGHT; - last1 = nRow - 3; - } - else { - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); - tableID->last1 = last1; - } - if (nCol == 2) { - if (extrapolate1 == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double u10 = TABLE_COL0(last1 + 1); - const double u11 = TABLE_COL0(last1 + 2); - const double y0 = TABLE(last1 + 1, 1); - const double y1 = TABLE(last1 + 2, 1); - LINEAR(u1, u10, u11, y0, y1); - break; - } - - case CONSTANT_SEGMENTS: - if (u1 >= TABLE_COL0(last1 + 2)) { - last1++; - } - y = TABLE(last1 + 1, 1); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last1]; - const double v = u1 - TABLE_COL0(last1 + 1); - y = TABLE(last1 + 1, 1); /* c[3] = y0 */ - y += ((c[0]*v + c[1])*v + c[2])*v; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: { - const double u10 = TABLE_COL0(last1 + 1); - const double u11 = TABLE_COL0(last1 + 2); - const double y0 = TABLE(last1 + 1, 1); - const double y1 = TABLE(last1 + 2, 1); - LINEAR(u1, u10, u11, y0, y1); - break; - } - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last1]; - if (extrapolate1 == LEFT) { - LINEAR_SLOPE(TABLE(1, 1), c[2], u1 - u1Min); - } - else /* if (extrapolate1 == RIGHT) */ { - const double v1 = u1Max - TABLE_COL0(nRow - 2); - LINEAR_SLOPE(TABLE(nRow - 1, 1), (3*c[0]*v1 + - 2*c[1])*v1 + c[2], u1 - u1Max); - } - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - y = (extrapolate1 == RIGHT) ? TABLE(nRow - 1, 1) : - TABLE(1, 1); - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", u1, - (extrapolate1 == LEFT) ? "greater" : "less", - (extrapolate1 == LEFT) ? "minimum" : "maximum", - (extrapolate1 == LEFT) ? "u_min[1]" : "u_max[1]", - (extrapolate1 == LEFT) ? u1Min : u1Max); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - } - else if (nCol > 2) { - enum PointInterval extrapolate2 = IN_TABLE; - size_t last2; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = u2Max - u2Min; - - if (u2 < u2Min) { - do { - u2 += T; - } while (u2 < u2Min); - } - else if (u2 > u2Max) { - do { - u2 -= T; - } while (u2 > u2Max); - } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - else if (u2 < u2Min) { - extrapolate2 = LEFT; - last2 = 0; - } - else if (u2 > u2Max) { - extrapolate2 = RIGHT; - last2 = nCol - 3; - } - else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - - if (extrapolate1 == IN_TABLE) { - if (extrapolate2 == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - BILINEAR(u1, u2); - break; - - case CONSTANT_SEGMENTS: - if (u1 >= TABLE_COL0(last1 + 2)) { - last1++; - } - if (u2 >= TABLE_ROW0(last2 + 2)) { - last2++; - } - y = TABLE(last1 + 1, last2 + 1); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, last2, nCol - 2)]; - double p1, p2, p3; - u1 -= TABLE_COL0(last1 + 1); - u2 -= TABLE_ROW0(last2 + 1); - p1 = ((c[0]*u2 + c[1])*u2 + c[2])*u2 + c[3]; - p2 = ((c[4]*u2 + c[5])*u2 + c[6])*u2 + c[7]; - p3 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - y = TABLE(last1 + 1, last2 + 1); /* c[15] = y00 */ - y += ((c[12]*u2 + c[13])*u2 + c[14])*u2; /* p4 */ - y += ((p1*u1 + p2)*u1 + p3)*u1; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - } - else if (extrapolate2 == LEFT) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, 0, nCol - 2)]; - double der_y2; - u1 -= TABLE_COL0(last1 + 1); - der_y2 = ((c[2]*u1 + c[6])*u1 + c[10])*u1 + c[14]; - y = TABLE(last1 + 1, 1); /* c[15] = y00 */ - y += ((c[3]*u1 + c[7])*u1 + c[11])*u1; - y += der_y2*(u2 - u2Min); - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double u10 = TABLE_COL0(last1 + 1); - const double u11 = TABLE_COL0(last1 + 2); - const double y00 = TABLE(last1 + 1, 1); - const double y10 = TABLE(last1 + 2, 1); - LINEAR(u1, u10, u11, y00, y10); - break; - } - - case CONSTANT_SEGMENTS: - if (u1 >= TABLE_COL0(last1 + 2)) { - last1++; - } - y = TABLE(last1 + 1, 1); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, 0, nCol - 2)]; - u1 -= TABLE_COL0(last1 + 1); - y = TABLE(last1 + 1, 1); /* c[15] = y00 */ - y += ((c[3]*u1 + c[7])*u1 + c[11])*u1; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u2 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[2] (=%lf) defined in the table.\n", u2, u2Min); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - else /* if (extrapolate2 == RIGHT) */ { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, nCol - 3, nCol - 2)]; - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - double der_y2; - u1 -= TABLE_COL0(last1 + 1); - y = TABLE(last1 + 1, nCol - 2); /* c[15] = y00 */ - p1 = ((c[0]*v2 + c[1])*v2 + c[2])*v2 + c[3]; - p2 = ((c[4]*v2 + c[5])*v2 + c[6])*v2 + c[7]; - p3 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - dp1_u2 = (3*c[0]*v2 + 2*c[1])*v2 + c[2]; - dp2_u2 = (3*c[4]*v2 + 2*c[5])*v2 + c[6]; - dp3_u2 = (3*c[8]*v2 + 2*c[9])*v2 + c[10]; - dp4_u2 = (3*c[12]*v2 + 2*c[13])*v2 + c[14]; - der_y2 = ((dp1_u2*u1 + dp2_u2)*u1 + dp3_u2)*u1 + dp4_u2; - y += ((c[12]*v2 + c[13])*v2 + c[14])*v2; /* p4 */ - y += ((p1*u1 + p2)*u1 + p3)*u1; - y += der_y2*(u2 - u2Max); - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double u10 = TABLE_COL0(last1 + 1); - const double u11 = TABLE_COL0(last1 + 2); - const double y01 = TABLE(last1 + 1, nCol - 1); - const double y11 = TABLE(last1 + 2, nCol - 1); - LINEAR(u1, u10, u11, y01, y11); - break; - } - - case CONSTANT_SEGMENTS: - if (u1 >= TABLE_COL0(last1 + 2)) { - last1++; - } - y = TABLE(last1 + 1, nCol - 1); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, nCol - 3, nCol - 2)]; - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double p1, p2, p3; - u1 -= TABLE_COL0(last1 + 1); - y = TABLE(last1 + 1, nCol - 2); /* c[15] = y00 */ - p1 = ((c[0]*v2 + c[1])*v2 + c[2])*v2 + c[3]; - p2 = ((c[4]*v2 + c[5])*v2 + c[6])*v2 + c[7]; - p3 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - y += ((c[12]*v2 + c[13])*v2 + c[14])*v2; /* p4 */ - y += ((p1*u1 + p2)*u1 + p3)*u1; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u2 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[2] (=%lf) defined in the table.\n", u2, u2Max); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - } - else if (extrapolate1 == LEFT) { - if (extrapolate2 == IN_TABLE) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, last2, nCol - 2)]; - double der_y1; - u2 -= TABLE_ROW0(last2 + 1); - der_y1 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - y = TABLE(1, last2 + 1); /* c[15] = y00 */ - y += ((c[12]*u2 + c[13])*u2 + c[14])*u2; /* p4 */ - y += der_y1*(u1 - u1Min); - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double u20 = TABLE_ROW0(last2 + 1); - const double u21 = TABLE_ROW0(last2 + 2); - const double y00 = TABLE(1, last2 + 1); - const double y01 = TABLE(1, last2 + 2); - LINEAR(u2, u20, u21, y00, y01); - break; - } - - case CONSTANT_SEGMENTS: - if (u2 >= TABLE_ROW0(last2 + 2)) { - last2++; - } - y = TABLE(1, last2 + 1); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, last2, nCol - 2)]; - u2 -= TABLE_ROW0(last2 + 1); - y = TABLE(1, last2 + 1); /* c[15] = y00 */ - y += ((c[12]*u2 + c[13])*u2 + c[14])*u2; /* p4 */ - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[1] (=%lf) defined in the table.\n", u1, u1Min); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - else if (extrapolate2 == LEFT) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, 0, nCol - 2)]; - u1 -= u1Min; - u2 -= u2Min; - y = TABLE(1, 1); - y += c[11]*u1 + c[14]*u2 + c[10]*u1*u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - y = TABLE(1, 1); - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be greater " - "or equal\nthan the minimum abscissa value u_min[2] (=%lf) " - "defined in the table.\n", u1, u1Min, u2, u2Min); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - else /* if (extrapolate2 == RIGHT) */ { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, nCol - 3, nCol - 2)]; - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double der_y1, der_y2, der_y12; - u1 -= u1Min; - u2 -= u2Max; - der_y1 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - der_y2 =(3*c[12]*v2 + 2*c[13])*v2 + c[14]; - der_y12 = (3*c[8]*v2 + 2*c[9])*v2 + c[10]; - y = TABLE(1, nCol - 1); - y += der_y1*u1 + der_y2*u2 + der_y12*u1*u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - y = TABLE(1, nCol - 1); - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be less " - "or equal\nthan the maximum abscissa value u_max[2] (=%lf) " - "defined in the table.\n", u1, u1Min, u2, u2Max); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - } - else /* if (extrapolate1 == RIGHT) */ { - if (extrapolate2 == IN_TABLE) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3, last2, nCol - 2)]; - double p1, p2, p3; - double der_y1; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - u2 -= TABLE_ROW0(last2 + 1); - p1 = ((c[0]*u2 + c[1])*u2 + c[2])*u2 + c[3]; - p2 = ((c[4]*u2 + c[5])*u2 + c[6])*u2 + c[7]; - p3 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - der_y1 = (3*p1*v1 + 2*p2)*v1 + p3; - y = TABLE(nRow - 2, last2 + 1); /* c[15] = y00 */ - y += ((c[12]*u2 + c[13])*u2 + c[14])*u2; /* p4 */ - y += ((p1*v1 + p2)*v1 + p3)*v1; - y += der_y1*(u1 - u1Max); - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: { - const double u20 = TABLE_ROW0(last2 + 1); - const double u21 = TABLE_ROW0(last2 + 2); - const double y10 = TABLE(nRow - 1, last2 + 1); - const double y11 = TABLE(nRow - 1, last2 + 2); - LINEAR(u2, u20, u21, y10, y11); - break; - } - - case CONSTANT_SEGMENTS: - if (u2 >= TABLE_ROW0(last2 + 2)) { - last2++; - } - y = TABLE(nRow - 1, last2 + 1); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3, last2, nCol - 2)]; - double p1, p2, p3; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - u2 -= TABLE_ROW0(last2 + 1); - p1 = ((c[0]*u2 + c[1])*u2 + c[2])*u2 + c[3]; - p2 = ((c[4]*u2 + c[5])*u2 + c[6])*u2 + c[7]; - p3 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - y = TABLE(nRow - 2, last2 + 1); /* c[15] = y00 */ - y += ((c[12]*u2 + c[13])*u2 + c[14])*u2; /* p4 */ - y += ((p1*v1 + p2)*v1 + p3)*v1; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[1] (=%lf) defined in the table.\n", u1, u1Max); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - else if (extrapolate2 == LEFT) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3 , 0, nCol - 2)]; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - double der_y1, der_y2, der_y12; - u1 -= u1Max; - u2 -= u2Min; - der_y1 = (3*c[3]*v1 + 2*c[7])*v1 + c[11]; - der_y2 = ((c[2]*v1 + c[6])*v1 + c[10])*v1 + c[14]; - der_y12 = (3*c[2]*v1 + 2*c[6])*v1 + c[10]; - y = TABLE(nRow - 1, 1); - y += der_y1*u1 + der_y2*u2 + der_y12*u1*u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - y = TABLE(nRow - 1, 1); - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be greater " - "or equal\nthan the minimum abscissa value u_min[2] (=%lf) " - "defined in the table.\n", u1, u1Max, u2, u2Min); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - else /* if (extrapolate2 == RIGHT) */ { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3, nCol - 3, nCol - 2)]; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - double der_y1, der_y2, der_y12; - u1 -= u1Max; - u2 -= u2Max; - p1 = ((c[0]*v2 + c[1])*v2 + c[2])*v2 + c[3]; - p2 = ((c[4]*v2 + c[5])*v2 + c[6])*v2 + c[7]; - p3 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - dp1_u2 = (3*c[0]*v2 + 2*c[1])*v2 + c[2]; - dp2_u2 = (3*c[4]*v2 + 2*c[5])*v2 + c[6]; - dp3_u2 = (3*c[8]*v2 + 2*c[9])*v2 + c[10]; - dp4_u2 = (3*c[12]*v2 + 2*c[13])*v2 + c[14]; - der_y1 = (3*p1*v1 + 2*p2)*v1 + p3; - der_y2 = ((dp1_u2*v1 + dp2_u2)*v1 + dp3_u2)*v1 + dp4_u2; - der_y12 = (3*dp1_u2*v1 + 2*dp2_u2)*v1 + dp3_u2; - y = TABLE(nRow - 1, nCol - 1); - y += der_y1*u1 + der_y2*u2 + der_y12*u1*u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return y; - } - break; - - case HOLD_LAST_POINT: - y = TABLE(nRow - 1, nCol - 1); - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be less " - "or equal\nthan the maximum abscissa value u_max[2] (=%lf) " - "defined in the table.\n", u1, u1Max, u2, u2Max); - return y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return y; - } - } - } - } - } - } - return y; -} - -double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1, - double u2, double der_u1, - double der_u2) { - double der_y = 0; - CombiTable2D* tableID = (CombiTable2D*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const double u1Min = TABLE_COL0(1); - const double u1Max = TABLE_COL0(nRow - 1); - const double u2Min = TABLE_ROW0(1); - const double u2Max = TABLE_ROW0(nCol - 1); - - if (nRow == 2) { - if (nCol > 2) { - enum PointInterval extrapolate2 = IN_TABLE; - size_t last2; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = u2Max - u2Min; - - if (u2 < u2Min) { - do { - u2 += T; - } while (u2 < u2Min); - } - else if (u2 > u2Max) { - do { - u2 -= T; - } while (u2 > u2Max); - } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - else if (u2 < u2Min) { - extrapolate2 = LEFT; - last2 = 0; - } - else if (u2 > u2Max) { - extrapolate2 = RIGHT; - last2 = nCol - 3; - } - else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - - if (extrapolate2 == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - der_y = (TABLE(1, last2 + 2) - TABLE(1, last2 + 1))/ - (TABLE_ROW0(last2 + 2) - TABLE_ROW0(last2 + 1)); - der_y *= der_u2; - break; - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last2]; - const double u20 = TABLE_ROW0(last2 + 1); - u2 -= u20; - der_y = (3*c[0]*u2 + 2*c[1])*u2 + c[2]; - der_y *= der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - der_y = (TABLE(1, last2 + 2) - TABLE(1, last2 + 1))/ - (TABLE_ROW0(last2 + 2) - TABLE_ROW0(last2 + 1)); - der_y *= der_u2; - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last2]; - if (extrapolate2 == LEFT) { - der_y = c[2]; - } - else /* if (extrapolate2 == RIGHT) */ { - const double u20 = TABLE_ROW0(last2 + 1); - const double u21 = TABLE_ROW0(last2 + 2); - der_y = u21 - u20; - der_y = (3*c[0]*der_y + 2*c[1])*der_y + c[2]; - } - der_y *= der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u2 " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", u2, - (extrapolate2 == LEFT) ? "greater" : "less", - (extrapolate2 == LEFT) ? "minimum" : "maximum", - (extrapolate2 == LEFT) ? "u_min[2]" : "u_max[2]", - (extrapolate2 == LEFT) ? u2Min : u2Max); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - } - } - else if (nRow > 2) { - enum PointInterval extrapolate1 = IN_TABLE; - size_t last1; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = u1Max - u1Min; - - if (u1 < u1Min) { - do { - u1 += T; - } while (u1 < u1Min); - } - else if (u1 > u1Max) { - do { - u1 -= T; - } while (u1 > u1Max); - } - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); - tableID->last1 = last1; - } - else if (u1 < u1Min) { - extrapolate1 = LEFT; - last1 = 0; - } - else if (u1 > u1Max) { - extrapolate1 = RIGHT; - last1 = nRow - 3; - } - else { - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); - tableID->last1 = last1; - } - if (nCol == 2) { - if (extrapolate1 == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - der_y = (TABLE(last1 + 2, 1) - TABLE(last1 + 1, 1))/ - (TABLE_COL0(last1 + 2) - TABLE_COL0(last1 + 1)); - der_y *= der_u1; - break; - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last1]; - const double u10 = TABLE_COL0(last1 + 1); - u1 -= u10; - der_y = (3*c[0]*u1 + 2*c[1])*u1 + c[2]; - der_y *= der_u1; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - der_y = (TABLE(last1 + 2, 1) - TABLE(last1 + 1, 1))/ - (TABLE_COL0(last1 + 2) - TABLE_COL0(last1 + 1)); - der_y *= der_u1; - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last1]; - if (extrapolate1 == LEFT) { - der_y = c[2]; - } - else /* if (extrapolate1 == RIGHT) */ { - const double u10 = TABLE_COL0(last1 + 1); - const double u11 = TABLE_COL0(last1 + 2); - der_y = u11 - u10; - der_y = (3*c[0]*der_y + 2*c[1])*der_y + c[2]; - } - der_y *= der_u1; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", u1, - (extrapolate1 == LEFT) ? "greater" : "less", - (extrapolate1 == LEFT) ? "minimum" : "maximum", - (extrapolate1 == LEFT) ? "u_min[1]" : "u_max[1]", - (extrapolate1 == LEFT) ? u1Min : u1Max); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - } - else if (nCol > 2) { - enum PointInterval extrapolate2 = IN_TABLE; - size_t last2; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = u2Max - u2Min; - - if (u2 < u2Min) { - do { - u2 += T; - } while (u2 < u2Min); - } - else if (u2 > u2Max) { - do { - u2 -= T; - } while (u2 > u2Max); - } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - else if (u2 < u2Min) { - extrapolate2 = LEFT; - last2 = 0; - } - else if (u2 > u2Max) { - extrapolate2 = RIGHT; - last2 = nCol - 3; - } - else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - - if (extrapolate1 == IN_TABLE) { - if (extrapolate2 == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - BILINEAR_DER(u1, u2); - break; - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, last2, nCol - 2)]; - double der_y1, der_y2; - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - u1 -= TABLE_COL0(last1 + 1); - u2 -= TABLE_ROW0(last2 + 1); - p1 = ((c[0]*u2 + c[1])*u2 + c[2])*u2 + c[3]; - p2 = ((c[4]*u2 + c[5])*u2 + c[6])*u2 + c[7]; - p3 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - dp1_u2 = (3*c[0]*u2 + 2*c[1])*u2 + c[2]; - dp2_u2 = (3*c[4]*u2 + 2*c[5])*u2 + c[6]; - dp3_u2 = (3*c[8]*u2 + 2*c[9])*u2 + c[10]; - dp4_u2 = (3*c[12]*u2 + 2*c[13])*u2 + c[14]; - der_y1 = (3*p1*u1 + 2*p2)*u1 + p3; - der_y2 = ((dp1_u2*u1 + dp2_u2)*u1 + dp3_u2)*u1 + dp4_u2; - der_y = der_y1*der_u1 + der_y2*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - } - else if (extrapolate2 == LEFT) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, 0, nCol - 2)]; - double der_y1, der_y2; - u1 -= TABLE_COL0(last1 + 1); - u2 -= u2Min; - der_y1 = (3*c[3]*u1 + 2*c[7])*u1 + c[11]; - der_y1 += ((3*c[2]*u1 + 2*c[6])*u1 + c[10])*u2; - der_y2 = ((c[2]*u1 + c[6])*u1 + c[10])*u1 + c[14]; - der_y = der_y1*der_u1 + der_y2*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u2 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[2] (=%lf) defined in the table.\n", u2, u2Min); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - else /* if (extrapolate2 == RIGHT) */ { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, nCol - 3, nCol - 2)]; - double der_y1, der_y2; - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - u1 -= TABLE_COL0(last1 + 1); - u2 -= u2Max; - p1 = ((c[0]*v2 + c[1])*v2 + c[2])*v2 + c[3]; - p2 = ((c[4]*v2 + c[5])*v2 + c[6])*v2 + c[7]; - p3 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - dp1_u2 = (3*c[0]*v2 + 2*c[1])*v2 + c[2]; - dp2_u2 = (3*c[4]*v2 + 2*c[5])*v2 + c[6]; - dp3_u2 = (3*c[8]*v2 + 2*c[9])*v2 + c[10]; - dp4_u2 = (3*c[12]*v2 + 2*c[13])*v2 + c[14]; - der_y1 = (3*p1*u1 + 2*p2)*u1 + p3; - der_y1 += ((3*dp1_u2*u1 + 2*dp2_u2)*u1 + dp3_u2)*u2; - der_y2 = ((dp1_u2*u1 + dp2_u2)*u1 + dp3_u2)*u1 + dp4_u2; - der_y = der_y1*der_u1 + der_y2*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u2 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[2] (=%lf) defined in the table.\n", u2, u2Max); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - } - else if (extrapolate1 == LEFT) { - if (extrapolate2 == IN_TABLE) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, last2, nCol - 2)]; - double der_y1, der_y2; - u1 -= u1Min; - u2 -= TABLE_ROW0(last2 + 1); - der_y1 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - der_y2 = (3*c[12]*u2 + 2*c[13])*u2 + c[14]; - der_y2 += ((3*c[8]*u2 + 2*c[9])*u2 + c[10])*u1; - der_y = der_y1*der_u1 + der_y2*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[1] (=%lf) defined in the table.\n", u1, u1Min); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - else if (extrapolate2 == LEFT) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, 0, nCol - 2)]; - u1 -= u1Min; - u2 -= u2Min; - der_y = (c[11] + c[10]*u2)*der_u1; - der_y += (c[14] + c[10]*u1)*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be greater " - "or equal\nthan the minimum abscissa value u_min[2] (=%lf) " - "defined in the table.\n", u1, u1Min, u2, u2Min); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - else /* if (extrapolate2 == RIGHT) */ { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, nCol - 3, nCol - 2)]; - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double der_y1, der_y2, der_y12; - u1 -= u1Min; - u2 -= u2Max; - der_y1 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - der_y2 =(3*c[12]*v2 + 2*c[13])*v2 + c[14]; - der_y12 = (3*c[8]*v2 + 2*c[9])*v2 + c[10]; - der_y = (der_y1 + der_y12*u2)*der_u1; - der_y += (der_y2 + der_y12*u1)*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be less " - "or equal\nthan the maximum abscissa value u_max[2] (=%lf) " - "defined in the table.\n", u1, u1Min, u2, u2Max); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - } - else /* if (extrapolate1 == RIGHT) */ { - if (extrapolate2 == IN_TABLE) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3, last2, nCol - 2)]; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - double der_y1, der_y2; - u1 -= u1Max; - u2 -= TABLE_ROW0(last2 + 1); - p1 = ((c[0]*u2 + c[1])*u2 + c[2])*u2 + c[3]; - p2 = ((c[4]*u2 + c[5])*u2 + c[6])*u2 + c[7]; - p3 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - dp1_u2 = (3*c[0]*u2 + 2*c[1])*u2 + c[2]; - dp2_u2 = (3*c[4]*u2 + 2*c[5])*u2 + c[6]; - dp3_u2 = (3*c[8]*u2 + 2*c[9])*u2 + c[10]; - dp4_u2 = (3*c[12]*u2 + 2*c[13])*u2 + c[14]; - der_y1 = (3*p1*v1 + 2*p2)*v1 + p3; - der_y2 = ((dp1_u2*v1 + dp2_u2)*v1 + dp3_u2)*v1 + dp4_u2; - der_y2 += ((3*dp1_u2*v1 + 2*dp2_u2)*v1 + dp3_u2)*u1; - der_y = der_y1*der_u1 + der_y2*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[1] (=%lf) defined in the table.\n", u1, u1Max); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - else if (extrapolate2 == LEFT) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3, 0, nCol - 2)]; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - double der_y1, der_y2, der_y12; - u1 -= u1Max; - u2 -= u2Min; - der_y1 = (3*c[3]*v1 + 2*c[7])*v1 + c[11]; - der_y2 = ((c[2]*v1 + c[6])*v1 + c[10])*v1 + c[14]; - der_y12 = (3*c[2]*v1 + 2*c[6])*v1 + c[10]; - der_y = (der_y1 + der_y12*u2)*der_u1; - der_y += (der_y2 + der_y12*u1)*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be greater " - "or equal\nthan the minimum abscissa value u_min[2] (=%lf) " - "defined in the table.\n", u1, u1Max, u2, u2Min); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - else /* if (extrapolate2 == RIGHT) */ { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3, nCol - 3, nCol - 2)]; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - double der_y1, der_y2, der_y12; - u1 -= u1Max; - u2 -= u2Max; - p1 = ((c[0]*v2 + c[1])*v2 + c[2])*v2 + c[3]; - p2 = ((c[4]*v2 + c[5])*v2 + c[6])*v2 + c[7]; - p3 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - dp1_u2 = (3*c[0]*v2 + 2*c[1])*v2 + c[2]; - dp2_u2 = (3*c[4]*v2 + 2*c[5])*v2 + c[6]; - dp3_u2 = (3*c[8]*v2 + 2*c[9])*v2 + c[10]; - dp4_u2 = (3*c[12]*v2 + 2*c[13])*v2 + c[14]; - der_y1 = (3*p1*v1 + 2*p2)*v1 + p3; - der_y2 = ((dp1_u2*v1 + dp2_u2)*v1 + dp3_u2)*v1 + dp4_u2; - der_y12 = (3*dp1_u2*v1 + 2*dp2_u2)*v1 + dp3_u2; - der_y = (der_y1 + der_y12*u2)*der_u1; - der_y += (der_y2 + der_y12*u1)*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be less " - "or equal\nthan the maximum abscissa value u_max[2] (=%lf) " - "defined in the table.\n", u1, u1Max, u2, u2Max); - return der_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der_y; - } - } - } - } - } - } - return der_y; -} - -double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u1, - double u2, double der_u1, - double der_u2, double der2_u1, - double der2_u2) { - double der2_y = 0; - CombiTable2D* tableID = (CombiTable2D*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const double u1Min = TABLE_COL0(1); - const double u1Max = TABLE_COL0(nRow - 1); - const double u2Min = TABLE_ROW0(1); - const double u2Max = TABLE_ROW0(nCol - 1); - - if (nRow == 2) { - if (nCol > 2) { - enum PointInterval extrapolate2 = IN_TABLE; - size_t last2; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = u2Max - u2Min; - - if (u2 < u2Min) { - do { - u2 += T; - } while (u2 < u2Min); - } - else if (u2 > u2Max) { - do { - u2 -= T; - } while (u2 > u2Max); - } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - else if (u2 < u2Min) { - extrapolate2 = LEFT; - last2 = 0; - } - else if (u2 > u2Max) { - extrapolate2 = RIGHT; - last2 = nCol - 3; - } - else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - - if (extrapolate2 == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - der2_y = (TABLE(1, last2 + 2) - TABLE(1, last2 + 1))/ - (TABLE_ROW0(last2 + 2) - TABLE_ROW0(last2 + 1)); - der2_y *= der2_u2; - break; - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last2]; - const double u20 = TABLE_ROW0(last2 + 1); - u2 -= u20; - der2_y = (3*c[0]*u2 + 2*c[1])*u2 + c[2]; - der2_y *= der2_u2; - der2_y += (6*c[0]*u2 + 2*c[1])*der_u2*der_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - der2_y = (TABLE(1, last2 + 2) - TABLE(1, last2 + 1))/ - (TABLE_ROW0(last2 + 2) - TABLE_ROW0(last2 + 1)); - der2_y *= der2_u2; - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last2]; - if (extrapolate2 == LEFT) { - der2_y = c[2]; - } - else /* if (extrapolate2 == RIGHT) */ { - const double u20 = TABLE_ROW0(last2 + 1); - const double u21 = TABLE_ROW0(last2 + 2); - der2_y = u21 - u20; - der2_y = (3*c[0]*der2_y + 2*c[1])*der2_y + c[2]; - } - der2_y *= der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u2 " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", u2, - (extrapolate2 == LEFT) ? "greater" : "less", - (extrapolate2 == LEFT) ? "minimum" : "maximum", - (extrapolate2 == LEFT) ? "u_min[2]" : "u_max[2]", - (extrapolate2 == LEFT) ? u2Min : u2Max); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - } - } - else if (nRow > 2) { - enum PointInterval extrapolate1 = IN_TABLE; - size_t last1; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = u1Max - u1Min; - - if (u1 < u1Min) { - do { - u1 += T; - } while (u1 < u1Min); - } - else if (u1 > u1Max) { - do { - u1 -= T; - } while (u1 > u1Max); - } - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); - tableID->last1 = last1; - } - else if (u1 < u1Min) { - extrapolate1 = LEFT; - last1 = 0; - } - else if (u1 > u1Max) { - extrapolate1 = RIGHT; - last1 = nRow - 3; - } - else { - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); - tableID->last1 = last1; - } - if (nCol == 2) { - if (extrapolate1 == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - der2_y = (TABLE(last1 + 2, 1) - TABLE(last1 + 1, 1))/ - (TABLE_COL0(last1 + 2) - TABLE_COL0(last1 + 1)); - der2_y *= der2_u1; - break; - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last1]; - const double u10 = TABLE_COL0(last1 + 1); - u1 -= u10; - der2_y = (3*c[0]*u1 + 2*c[1])*u1 + c[2]; - der2_y *= der2_u1; - der2_y += (6*c[0]*u1 + 2*c[1])*der_u1*der_u1; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - } - else { - /* Extrapolation */ - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - der2_y = (TABLE(last1 + 2, 1) - TABLE(last1 + 1, 1))/ - (TABLE_COL0(last1 + 2) - TABLE_COL0(last1 + 1)); - der2_y *= der2_u1; - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[last1]; - if (extrapolate1 == LEFT) { - der2_y = c[2]; - } - else /* if (extrapolate1 == RIGHT) */ { - const double u10 = TABLE_COL0(last1 + 1); - const double u11 = TABLE_COL0(last1 + 2); - der2_y = u11 - u10; - der2_y = (3*c[0]*der2_y + 2*c[1])*der2_y + c[2]; - } - der2_y *= der2_u1; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be %s or equal\nthan the %s abscissa " - "value %s (=%lf) defined in the table.\n", u1, - (extrapolate1 == LEFT) ? "greater" : "less", - (extrapolate1 == LEFT) ? "minimum" : "maximum", - (extrapolate1 == LEFT) ? "u_min[1]" : "u_max[1]", - (extrapolate1 == LEFT) ? u1Min : u1Max); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - } - else if (nCol > 2) { - enum PointInterval extrapolate2 = IN_TABLE; - size_t last2; - - /* Periodic extrapolation */ - if (tableID->extrapolation == PERIODIC) { - const double T = u2Max - u2Min; - - if (u2 < u2Min) { - do { - u2 += T; - } while (u2 < u2Min); - } - else if (u2 > u2Max) { - do { - u2 -= T; - } while (u2 > u2Max); - } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - else if (u2 < u2Min) { - extrapolate2 = LEFT; - last2 = 0; - } - else if (u2 > u2Max) { - extrapolate2 = RIGHT; - last2 = nCol - 3; - } - else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); - tableID->last2 = last2; - } - - if (extrapolate1 == IN_TABLE) { - if (extrapolate2 == IN_TABLE) { - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - BILINEAR_DER2(u1, u2); - break; - - case CONSTANT_SEGMENTS: - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, last2, nCol - 2)]; - double der_y1, der_y2, der2_y1, der2_y2; - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - double d2p1_u2, d2p2_u2, d2p3_u2, d2p4_u2; - u1 -= TABLE_COL0(last1 + 1); - u2 -= TABLE_ROW0(last2 + 1); - p1 = ((c[0]*u2 + c[1])*u2 + c[2])*u2 + c[3]; - p2 = ((c[4]*u2 + c[5])*u2 + c[6])*u2 + c[7]; - p3 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - dp1_u2 = (3*c[0]*u2 + 2*c[1])*u2 + c[2]; - dp2_u2 = (3*c[4]*u2 + 2*c[5])*u2 + c[6]; - dp3_u2 = (3*c[8]*u2 + 2*c[9])*u2 + c[10]; - dp4_u2 = (3*c[12]*u2 + 2*c[13])*u2 + c[14]; - d2p1_u2 = 6*c[0]*u2 + 2*c[1]; - d2p2_u2 = 6*c[4]*u2 + 2*c[5]; - d2p3_u2 = 6*c[8]*u2 + 2*c[9]; - d2p4_u2 = 6*c[12]*u2 + 2*c[13]; - der_y1 = (3*p1*u1 + 2*p2)*u1 + p3; - der_y2 = ((dp1_u2*u1 + dp2_u2)*u1 + dp3_u2)*u1 + dp4_u2; - der2_y1 = 6*p1*u1 + 2*p2; - der2_y2 = ((d2p1_u2*u1 + d2p2_u2)*u1 + d2p3_u2)*u1 + d2p4_u2; - der2_y = der2_y1*der_u1*der_u1 + der_y1*der2_u1; - der2_y += ((6*dp1_u2*u1 + 4*dp2_u2)*u1 + 2*dp3_u2)*der_u1*der_u2; - der2_y += der2_y2*der_u2*der_u2 + der_y2*der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - } - else if (extrapolate2 == LEFT) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER2(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, 0, nCol - 2)]; - double der_y1, der_y2, der2_y1; - u1 -= TABLE_COL0(last1 + 1); - u2 -= u2Min; - der_y1 = (3*c[3]*u1 + 2*c[7])*u1 + c[11]; - der_y1 += ((3*c[2]*u1 + 2*c[6])*u1 + c[10])*u2; - der_y2 = ((c[2]*u1 + c[6])*u1 + c[10])*u1 + c[14]; - der2_y1 = 2*(3*c[3]*u1 + c[7] + (3*c[2]*u1 + c[6]))*u2; - der2_y = der2_y1*der_u1*der_u1 + der_y1*der2_u1; - der2_y += 2*((3*c[2]*u1 + 2*c[6])*u1 + c[10])*der_u1*der_u2; - der2_y += der_y2*der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u2 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[2] (=%lf) defined in the table.\n", u2, u2Min); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - else /* if (extrapolate2 == RIGHT) */ { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER2(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(last1, nCol - 3, nCol - 2)]; - double der_y1, der_y2; - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - u1 -= TABLE_COL0(last1 + 1); - u2 -= u2Max; - p1 = ((c[0]*v2 + c[1])*v2 + c[2])*v2 + c[3]; - p2 = ((c[4]*v2 + c[5])*v2 + c[6])*v2 + c[7]; - p3 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - dp1_u2 = (3*c[0]*v2 + 2*c[1])*v2 + c[2]; - dp2_u2 = (3*c[4]*v2 + 2*c[5])*v2 + c[6]; - dp3_u2 = (3*c[8]*v2 + 2*c[9])*v2 + c[10]; - dp4_u2 = (3*c[12]*v2 + 2*c[13])*v2 + c[14]; - der_y1 = (3*p1*u1 + 2*p2)*u1 + p3; - der_y1 += ((3*dp1_u2*u1 + 2*dp2_u2)*u1 + dp3_u2)*u2; - der_y2 = ((dp1_u2*u1 + dp2_u2)*u1 + dp3_u2)*u1 + dp4_u2; - der2_y = 2*(p2 + dp2_u2*u2 + 3*u1*(p1 + dp1_u2*u2))*der_u1*der_u1; - der2_y += 2*(dp3_u2 + u1*(2*dp2_u2 + 3*dp1_u2*u1))*der_u1*der_u2; - der2_y += der_y1*der2_u1 + der_y2*der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u2 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[2] (=%lf) defined in the table.\n", u2, u2Max); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - } - else if (extrapolate1 == LEFT) { - if (extrapolate2 == IN_TABLE) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER2(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, last2, nCol - 2)]; - double der_y1, der_y2; - u1 -= u1Min; - u2 -= TABLE_ROW0(last2 + 1); - der_y1 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - der_y2 = (3*c[12]*u2 + 2*c[13])*u2 + c[14]; - der_y2 += ((3*c[8]*u2 + 2*c[9])*u2 + c[10])*u1; - der2_y = 2*((3*c[8]*u2 + 2*c[9])*u2 + c[10])*der_u1*der_u2; - der2_y += 2*(c[13] + c[9]*u1 + 3*(c[12] + c[8]*u1)*u2)*der_u2*der_u2; - der2_y += der_y1*der2_u1 + der_y2*der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[1] (=%lf) defined in the table.\n", u1, u1Min); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - else if (extrapolate2 == LEFT) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER2(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, 0, nCol - 2)]; - u1 -= u1Min; - u2 -= u2Min; - der2_y = 2*c[10]*der_u1*der_u2; - der2_y += (c[11] + c[10]*u2)*der2_u1; - der2_y += (c[14] + c[10]*u1)*der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be greater " - "or equal\nthan the minimum abscissa value u_min[2] (=%lf) " - "defined in the table.\n", u1, u1Min, u2, u2Min); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - else /* if (extrapolate2 == RIGHT) */ { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER2(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(0, nCol - 3, nCol - 2)]; - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double der_y1, der_y2, der_y12; - u1 -= u1Min; - u2 -= u2Max; - der_y1 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - der_y2 =(3*c[12]*v2 + 2*c[13])*v2 + c[14]; - der_y12 = (3*c[8]*v2 + 2*c[9])*v2 + c[10]; - der2_y = 2*der_y12*der_u1*der_u2; - der2_y += (der_y1 + der_y12*u2)*der2_u1; - der2_y += (der_y2 + der_y12*u1)*der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be greater or equal\nthan the minimum abscissa " - "value u_min[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be less " - "or equal\nthan the maximum abscissa value u_max[2] (=%lf) " - "defined in the table.\n", u1, u1Min, u2, u2Max); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - } - else /* if (extrapolate1 == RIGHT) */ { - if (extrapolate2 == IN_TABLE) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER2(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3, last2, nCol - 2)]; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - double der_y1, der_y2; - u1 -= u1Max; - u2 -= TABLE_ROW0(last2 + 1); - p1 = ((c[0]*u2 + c[1])*u2 + c[2])*u2 + c[3]; - p2 = ((c[4]*u2 + c[5])*u2 + c[6])*u2 + c[7]; - p3 = ((c[8]*u2 + c[9])*u2 + c[10])*u2 + c[11]; - dp1_u2 = (3*c[0]*u2 + 2*c[1])*u2 + c[2]; - dp2_u2 = (3*c[4]*u2 + 2*c[5])*u2 + c[6]; - dp3_u2 = (3*c[8]*u2 + 2*c[9])*u2 + c[10]; - dp4_u2 = (3*c[12]*u2 + 2*c[13])*u2 + c[14]; - der_y1 = (3*p1*v1 + 2*p2)*v1 + p3; - der_y2 = ((dp1_u2*v1 + dp2_u2)*v1 + dp3_u2)*v1 + dp4_u2; - der_y2 += ((3*dp1_u2*v1 + 2*dp2_u2)*v1 + dp3_u2)*u1; - der2_y = 2*(c[10] + v1*(2*c[6] + 3*c[2]*v1) + - 2*(c[9] + v1*(2*c[5] + 3*c[1]*v1))*u2 + - 3*(c[8] + v1*(2*c[4] + 3*c[0]*v1))*u2*u2)*der_u1*der_u2; - der2_y += 2*(c[13] + v1*(c[9] + v1*(c[5] + c[1]*v1)) + - 3*(c[12] + v1*(c[8] + v1*(c[4] + c[0]*v1)))*u2 + - u1*(c[9] + v1*(2*c[5] + 3*c[1]*v1) + - 3*(c[8] + v1*(2*c[4] + 3*c[0]*v1))*u2))*der_u2*der_u2; - der2_y += der_y1*der2_u1 + der_y2*der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[1] (=%lf) defined in the table.\n", u1, u1Max); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - else if (extrapolate2 == LEFT) { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER2(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3, 0, nCol - 2)]; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - double der_y1, der_y2, der_y12; - u1 -= u1Max; - u2 -= u2Min; - der_y1 = (3*c[3]*v1 + 2*c[7])*v1 + c[11]; - der_y2 = ((c[2]*v1 + c[6])*v1 + c[10])*v1 + c[14]; - der_y12 = (3*c[2]*v1 + 2*c[6])*v1 + c[10]; - der2_y = 2*der_y12*der_u1*der_u2; - der2_y += (der_y1 + der_y12*u2)*der2_u1; - der2_y += (der_y2 + der_y12*u1)*der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be greater " - "or equal\nthan the minimum abscissa value u_min[2] (=%lf) " - "defined in the table.\n", u1, u1Max, u2, u2Min); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - else /* if (extrapolate2 == RIGHT) */ { - switch (tableID->extrapolation) { - case LAST_TWO_POINTS: - switch (tableID->smoothness) { - case LINEAR_SEGMENTS: - case CONSTANT_SEGMENTS: - BILINEAR_DER2(u1, u2); - break; - - case AKIMA_C1: - if (NULL != tableID->spline) { - const double* c = tableID->spline[ - IDX(nRow - 3, nCol - 3, nCol - 2)]; - const double v1 = u1Max - TABLE_COL0(nRow - 2); - const double v2 = u2Max - TABLE_ROW0(nCol - 2); - double p1, p2, p3; - double dp1_u2, dp2_u2, dp3_u2, dp4_u2; - double der_y1, der_y2, der_y12; - u1 -= u1Max; - u2 -= u2Max; - p1 = ((c[0]*v2 + c[1])*v2 + c[2])*v2 + c[3]; - p2 = ((c[4]*v2 + c[5])*v2 + c[6])*v2 + c[7]; - p3 = ((c[8]*v2 + c[9])*v2 + c[10])*v2 + c[11]; - dp1_u2 = (3*c[0]*v2 + 2*c[1])*v2 + c[2]; - dp2_u2 = (3*c[4]*v2 + 2*c[5])*v2 + c[6]; - dp3_u2 = (3*c[8]*v2 + 2*c[9])*v2 + c[10]; - dp4_u2 = (3*c[12]*v2 + 2*c[13])*v2 + c[14]; - der_y1 = (3*p1*v1 + 2*p2)*v1 + p3; - der_y2 = ((dp1_u2*v1 + dp2_u2)*v1 + dp3_u2)*v1 + dp4_u2; - der_y12 = (3*dp1_u2*v1 + 2*dp2_u2)*v1 + dp3_u2; - der2_y = 2*der_y12*der_u1*der_u2; - der2_y += (der_y1 + der_y12*u2)*der2_u1; - der2_y += (der_y2 + der_y12*u1)*der2_u2; - } - break; - - case MAKIMA_C1: - ModelicaError("Bivariate modified Akima interpolation is " - "not implemented\n"); - return der2_y; - - case FRITSCH_BUTLAND_MONOTONE_C1: - case STEFFEN_MONOTONE_C1: - ModelicaError("Bivariate monotone C1 interpolation is " - "not implemented\n"); - return der2_y; - - default: - ModelicaError("Unknown smoothness kind\n"); - return der2_y; - } - break; - - case HOLD_LAST_POINT: - break; - - case NO_EXTRAPOLATION: - ModelicaFormatError("Extrapolation error: The value u1 " - "(=%lf) must be less or equal\nthan the maximum abscissa " - "value u_max[1] (=%lf) defined in the table.\n" - "Extrapolation error: The value u2 (=%lf) must be less " - "or equal\nthan the maximum abscissa value u_max[2] (=%lf) " - "defined in the table.\n", u1, u1Max, u2, u2Max); - return der2_y; - - case PERIODIC: - /* Should not be possible to get here */ - break; - - default: - ModelicaError("Unknown extrapolation kind\n"); - return der2_y; - } - } - } - } - } - } - return der2_y; -} - -void ModelicaStandardTables_CombiTable2D_minimumAbscissa(void* _tableID, - _Inout_ double* uMin) { - CombiTable2D* tableID = (CombiTable2D*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - const size_t nCol = tableID->nCol; - uMin[0] = TABLE_COL0(1); - uMin[1] = TABLE_ROW0(1); - } - else { - uMin[0] = 0.; - uMin[1] = 0.; - } -} - -void ModelicaStandardTables_CombiTable2D_maximumAbscissa(void* _tableID, - _Inout_ double* uMax) { - CombiTable2D* tableID = (CombiTable2D*)_tableID; - if (NULL != tableID && NULL != tableID->table) { - const double* table = tableID->table; - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - uMax[0] = TABLE_COL0(nRow - 1); - uMax[1] = TABLE_ROW0(nCol - 1); - } - else { - uMax[0] = 0.; - uMax[1] = 0.; - } -} - -double ModelicaStandardTables_CombiTable2D_read(void* _tableID, int force, - int verbose) { -#if !defined(NO_FILE_SYSTEM) - CombiTable2D* tableID = (CombiTable2D*)_tableID; - if (NULL != tableID && tableID->source == TABLESOURCE_FILE) { - if (force || NULL == tableID->table) { - const char* fileName = tableID->key; - const char* tableName = tableID->key + strlen(fileName) + 1; -#if defined(TABLE_SHARE) - TableShare* file = readTable(fileName, tableName, &tableID->nRow, - &tableID->nCol, verbose, force, ",", 0); - if (NULL != file) { - tableID->table = file->table; - } - else { - return 0.; /* Error */ - } -#else - if (NULL != tableID->table) { - free(tableID->table); - } - tableID->table = readTable(fileName, tableName, &tableID->nRow, - &tableID->nCol, verbose, force, ",", 0); -#endif - if (NULL == tableID->table) { - return 0.; /* Error */ - } - if (isValidCombiTable2D(tableID, tableName, NO_CLEANUP) == 0) { - return 0.; /* Error */ - } - if (tableID->smoothness == AKIMA_C1 && - tableID->nRow <= 3 && tableID->nCol <= 3) { - tableID->smoothness = LINEAR_SEGMENTS; - } - /* Reinitialization of the Akima-spline coefficients */ - if (tableID->smoothness == AKIMA_C1) { - spline2DClose(&tableID->spline); - tableID->spline = spline2DInit((const double*)tableID->table, - tableID->nRow,tableID->nCol); - if (NULL == tableID->spline) { - ModelicaError("Memory allocation error\n"); - return 0.; /* Error */ - } - } - } - } -#endif - return 1.; /* Success */ -} - -/* ----- Internal functions ----- */ - -static int isNearlyEqual(double x, double y) { - const double fx = fabs(x); - const double fy = fabs(y); - double cmp = fx > fy ? fx : fy; - if (cmp < _EPSILON) { - cmp = _EPSILON; - } - cmp *= _EPSILON; - return fabs(y - x) < cmp; -} - -static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, - size_t last, double x) { - size_t i0 = 0; - size_t i1 = nRow - 1; - if (x < TABLE_COL0(last)) { - i1 = last; - } - else if (x >= TABLE_COL0(last + 1)) { - i0 = last; - } - else { - return last; - } - - /* Binary search */ - while (i1 > i0 + 1) { - const size_t i = (i0 + i1)/2; - if (x < TABLE_COL0(i)) { - i1 = i; - } - else { - i0 = i; - } - } - return i0; -} - -static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, - double x) { - size_t i0 = 0; - size_t i1 = nCol - 1; - if (x < TABLE_ROW0(last)) { - i1 = last; - } - else if (x >= TABLE_ROW0(last + 1)) { - i0 = last; - } - else { - return last; - } - - /* Binary search */ - while (i1 > i0 + 1) { - const size_t i = (i0 + i1)/2; - if (x < TABLE_ROW0(i)) { - i1 = i; - } - else { - i0 = i; - } - } - return i0; -} - -/* ----- Internal check functions ----- */ - -static int isValidName(_In_z_ const char* name) { - int isValid = 0; - if (NULL != name) { - if (strcmp(name, "NoName") != 0) { - size_t i; - size_t len = strlen(name); - for (i = 0; i < len; i++) { - if (name[i] != ' ') { - isValid = 1; - break; - } - } - } - } - return isValid; -} - -static int isValidCombiTimeTable(CombiTimeTable* tableID, - _In_z_ const char* _tableName, enum CleanUp cleanUp) { - int isValid = 1; - if (NULL != tableID) { - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const char* tableDummyName = "NoName"; - const char* tableName = _tableName[0] != '\0' ? _tableName : tableDummyName; - size_t iCol; - - /* Check dimensions */ - if (nRow < 1 || nCol < 2) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTimeTable_close(tableID); - } - ModelicaFormatError( - "Table matrix \"%s(%lu,%lu)\" does not have appropriate " - "dimensions for time interpolation.\n", tableName, - (unsigned long)nRow, (unsigned long)nCol); - isValid = 0; - return isValid; - } - - /* Check column indices */ - for (iCol = 0; iCol < tableID->nCols; ++iCol) { - const size_t col = (size_t)tableID->cols[iCol]; - if (col < 1 || col > tableID->nCol) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTimeTable_close(tableID); - } - ModelicaFormatError("The column index %lu is out of range " - "for table matrix \"%s(%lu,%lu)\".\n", (unsigned long)col, - tableName, (unsigned long)nRow, (unsigned long)nCol); - } - } - - if (NULL != tableID->table && nRow > 1) { - const double* table = tableID->table; - /* Check period */ - if (tableID->extrapolation == PERIODIC) { - const double tMin = TABLE_ROW0(0); - const double tMax = TABLE_COL0(nRow - 1); - const double T = tMax - tMin; - if (T <= 0) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTimeTable_close(tableID); - } - ModelicaFormatError( - "Table matrix \"%s\" does not have a positive period/cycle " - "time for time interpolation with periodic " - "extrapolation.\n", tableName); - isValid = 0; - return isValid; - } - } - - /* Check, whether first column values are monotonically or strictly - increasing */ - if (tableID->smoothness == AKIMA_C1 || - tableID->smoothness == MAKIMA_C1 || - tableID->smoothness == FRITSCH_BUTLAND_MONOTONE_C1 || - tableID->smoothness == STEFFEN_MONOTONE_C1) { - size_t i; - for (i = 0; i < nRow - 1; i++) { - double t0 = TABLE_COL0(i); - double t1 = TABLE_COL0(i + 1); - if (t0 >= t1) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTimeTable_close(tableID); - } - ModelicaFormatError( - "The values of the first column of table \"%s(%lu,%lu)\" " - "are not strictly increasing because %s(%lu,1) (=%lf) " - ">= %s(%lu,1) (=%lf).\n", tableName, (unsigned long)nRow, - (unsigned long)nCol, tableName, (unsigned long)i + 1, t0, - tableName, (unsigned long)i + 2, t1); - isValid = 0; - return isValid; - } - } - } - else { - size_t i; - for (i = 0; i < nRow - 1; i++) { - double t0 = TABLE_COL0(i); - double t1 = TABLE_COL0(i + 1); - if (t0 > t1) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTimeTable_close(tableID); - } - ModelicaFormatError( - "The values of the first column of table \"%s(%lu,%lu)\" " - "are not monotonically increasing because %s(%lu,1) " - "(=%lf) > %s(%lu,1) (=%lf).\n", tableName, - (unsigned long)nRow, (unsigned long)nCol, tableName, - (unsigned long)i + 1, t0, tableName, (unsigned long)i + - 2, t1); - isValid = 0; - return isValid; - } - } - } - } - } - - return isValid; -} - -static int isValidCombiTable1D(CombiTable1D* tableID, - _In_z_ const char* _tableName, enum CleanUp cleanUp) { - int isValid = 1; - if (NULL != tableID) { - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const char* tableDummyName = "NoName"; - const char* tableName = _tableName[0] != '\0' ? _tableName : tableDummyName; - size_t iCol; - - /* Check dimensions */ - if (nRow < 1 || nCol < 2) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTable1D_close(tableID); - } - ModelicaFormatError( - "Table matrix \"%s(%lu,%lu)\" does not have appropriate " - "dimensions for 1D-interpolation.\n", tableName, - (unsigned long)nRow, (unsigned long)nCol); - isValid = 0; - return isValid; - } - - /* Check column indices */ - for (iCol = 0; iCol < tableID->nCols; ++iCol) { - const size_t col = (size_t)tableID->cols[iCol]; - if (col < 1 || col > tableID->nCol) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTable1D_close(tableID); - } - ModelicaFormatError("The column index %lu is out of range " - "for table matrix \"%s(%lu,%lu)\".\n", (unsigned long)col, - tableName, (unsigned long)nRow, (unsigned long)nCol); - } - } - - if (NULL != tableID->table) { - const double* table = tableID->table; - size_t i; - /* Check, whether first column values are strictly increasing */ - for (i = 0; i < nRow - 1; i++) { - double x0 = TABLE_COL0(i); - double x1 = TABLE_COL0(i + 1); - if (x0 >= x1) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTable1D_close(tableID); - } - ModelicaFormatError( - "The values of the first column of table \"%s(%lu,%lu)\" are " - "not strictly increasing because %s(%lu,1) (=%lf) >= " - "%s(%lu,1) (=%lf).\n", tableName, (unsigned long)nRow, - (unsigned long)nCol, tableName, (unsigned long)i + 1, x0, - tableName, (unsigned long)i + 2, x1); - isValid = 0; - return isValid; - } - } - } - } - - return isValid; -} - -static int isValidCombiTable2D(CombiTable2D* tableID, - _In_z_ const char* _tableName, enum CleanUp cleanUp) { - int isValid = 1; - if (NULL != tableID) { - const size_t nRow = tableID->nRow; - const size_t nCol = tableID->nCol; - const char* tableDummyName = "NoName"; - const char* tableName = _tableName[0] != '\0' ? _tableName : tableDummyName; - - /* Check dimensions */ - if (nRow < 2 || nCol < 2) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTable2D_close(tableID); - } - ModelicaFormatError( - "Table matrix \"%s(%lu,%lu)\" does not have appropriate " - "dimensions for 2D-interpolation.\n", tableName, - (unsigned long)nRow, (unsigned long)nCol); - isValid = 0; - return isValid; - } - - if (NULL != tableID->table) { - const double* table = tableID->table; - size_t i; - /* Check, whether first column values are strictly increasing */ - for (i = 1; i < nRow - 1; i++) { - double x0 = TABLE_COL0(i); - double x1 = TABLE_COL0(i + 1); - if (x0 >= x1) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTable2D_close(tableID); - } - ModelicaFormatError( - "The values of the first column of table \"%s(%lu,%lu)\" are " - "not strictly increasing because %s(%lu,1) (=%lf) >= " - "%s(%lu,1) (=%lf).\n", tableName, (unsigned long)nRow, - (unsigned long)nCol, tableName, (unsigned long)i + 1, - x0, tableName, (unsigned long)i + 2, x1); - isValid = 0; - return isValid; - } - } - - /* Check, whether first row values are strictly increasing */ - for (i = 1; i < nCol - 1; i++) { - double y0 = TABLE_ROW0(i); - double y1 = TABLE_ROW0(i + 1); - if (y0 >= y1) { - if (DO_CLEANUP == cleanUp) { - ModelicaStandardTables_CombiTable2D_close(tableID); - } - ModelicaFormatError( - "The values of the first row of table \"%s(%lu,%lu)\" are " - "not strictly increasing because %s(1,%lu) (=%lf) >= " - "%s(1,%lu) (=%lf).\n", tableName, (unsigned long)nRow, - (unsigned long)nCol, tableName, (unsigned long)i + 1, - y0, tableName, (unsigned long)i + 2, y1); - isValid = 0; - return isValid; - } - } - } - } - - return isValid; -} - -static enum TableSource getTableSource(_In_z_ const char* fileName, - _In_z_ const char* tableName) { - enum TableSource tableSource; - int fileNameGiven = isValidName(fileName); - int tableNameGiven = isValidName(tableName); - - /* Determine in which way the table values are defined */ - if (tableNameGiven == 0) { - /* No table name is given */ - if (fileNameGiven != 0) { - ModelicaFormatError( - "The file name for a table (= \"%s\") is defined, " - "but not the corresponding table name.\n", fileName); - } - tableSource = TABLESOURCE_MODEL; - } - else { - /* A table name is given */ -#if defined(NO_FILE_SYSTEM) - if (fileNameGiven != 0) { - ModelicaFormatError( - "The file name (= \"%s\") for a table (= \"%s\") is defined. " - "Since Modelica is used in an environment where storage cannot " - "be allocated (#define NO_FILE_SYSTEM), tables cannot be read " - "from file.\n", fileName, tableName); - } - tableSource = TABLESOURCE_FUNCTION; -#else - tableSource = - fileNameGiven == 0 ? TABLESOURCE_FUNCTION : TABLESOURCE_FILE; -#endif - } - return tableSource; -} - -/* ----- Internal univariate spline functions ---- */ - -static CubicHermite1D* akimaSpline1DInit(_In_ const double* table, size_t nRow, - size_t nCol, _In_ const int* cols, - size_t nCols) { - /* Reference: - - Hiroshi Akima. A new method of interpolation and smooth curve fitting - based on local procedures. Journal of the ACM, 17(4), 589-602, Oct. 1970. - (https://dx.doi.org/10.1145/321607.321609) - */ - - CubicHermite1D* spline; - double* d; /* Divided differences */ - size_t col; - - /* Actually there is no need for consecutive memory */ - spline = (CubicHermite1D*)malloc((nRow - 1)*nCols*sizeof(CubicHermite1D)); - if (NULL == spline) { - return NULL; - } - - d = (double*)malloc((nRow + 3)*sizeof(double)); - if (NULL == d) { - free(spline); - return NULL; - } - - for (col = 0; col < nCols; col++) { - size_t i; - double c2; - - /* Calculation of the divided differences */ - for (i = 0; i < nRow - 1; i++) { - size_t c = (size_t)(cols[col] - 1); - d[i + 2] = (TABLE(i + 1, c) - TABLE(i, c))/ - (TABLE_COL0(i + 1) - TABLE_COL0(i)); - } - - /* Extrapolation using non-periodic boundary conditions */ - d[0] = 3*d[2] - 2*d[3]; - d[1] = 2*d[2] - d[3]; - d[nRow + 1] = 2*d[nRow] - d[nRow - 1]; - d[nRow + 2] = 3*d[nRow] - 2*d[nRow - 1]; - - /* Initialization of the left boundary slope */ - c2 = fabs(d[3] - d[2]) + fabs(d[1] - d[0]); - if (c2 > 0) { - const double a = fabs(d[1] - d[0])/c2; - c2 = (1 - a)*d[1] + a*d[2]; - } - else { - c2 = 0.5*d[1] + 0.5*d[2]; - } - - /* Calculation of the 3(4) coefficients per interval */ - for (i = 0; i < nRow - 1; i++) { - const double dx = TABLE_COL0(i + 1) - TABLE_COL0(i); - double* c = spline[IDX(i, col, nCols)]; - - c[2] = c2; - c2 = fabs(d[i + 4] - d[i + 3]) + fabs(d[i + 2] - d[i + 1]); - if (c2 > 0) { - const double a = fabs(d[i + 2] - d[i + 1])/c2; - c2 = (1 - a)*d[i + 2] + a*d[i + 3]; - } - else { - c2 = 0.5*d[i + 2] + 0.5*d[i + 3]; - } - c[1] = (3*d[i + 2] - 2*c[2] - c2)/dx; - c[0] = (c[2] + c2 - 2*d[i + 2])/(dx*dx); - /* No need to store the absolute term y0 */ - /* c[3] = TABLE(i, cols[col] - 1); */ - } - } - - free(d); - return spline; -} - -static CubicHermite1D* makimaSpline1DInit(_In_ const double* table, size_t nRow, - size_t nCol, _In_ const int* cols, - size_t nCols) { - /* Reference: - Method description taken from section "Modified Akima formula" of: - - Cosmin Ionita. Makima piecewise cubic interpolation, April 2019. - (https://blogs.mathworks.com/cleve/?p=4707) - */ - - CubicHermite1D* spline; - double* d; /* Divided differences */ - size_t col; - - /* Actually there is no need for consecutive memory */ - spline = (CubicHermite1D*)malloc((nRow - 1)*nCols*sizeof(CubicHermite1D)); - if (NULL == spline) { - return NULL; - } - - d = (double*)malloc((nRow + 3)*sizeof(double)); - if (NULL == d) { - free(spline); - return NULL; - } - - for (col = 0; col < nCols; col++) { - size_t i; - double c2; - - /* Calculation of the divided differences */ - for (i = 0; i < nRow - 1; i++) { - size_t c = (size_t)(cols[col] - 1); - d[i + 2] = (TABLE(i + 1, c) - TABLE(i, c))/ - (TABLE_COL0(i + 1) - TABLE_COL0(i)); - } - - /* Extrapolation using non-periodic boundary conditions */ - d[0] = 3*d[2] - 2*d[3]; - d[1] = 2*d[2] - d[3]; - d[nRow + 1] = 2*d[nRow] - d[nRow - 1]; - d[nRow + 2] = 3*d[nRow] - 2*d[nRow - 1]; - - /* Initialization of the left boundary slope */ - c2 = fabs(d[3] - d[2]) + fabs(d[1] - d[0]); - c2 += 0.5*fabs(d[3] + d[2]) + 0.5*fabs(d[1] + d[0]); - if (c2 > 0) { - const double a = (fabs(d[1] - d[0]) + 0.5*fabs(d[1] + d[0]))/c2; - c2 = (1 - a)*d[1] + a*d[2]; - } - else { - c2 = 0.0; - } - - /* Calculation of the 3(4) coefficients per interval */ - for (i = 0; i < nRow - 1; i++) { - const double dx = TABLE_COL0(i + 1) - TABLE_COL0(i); - double* c = spline[IDX(i, col, nCols)]; - - c[2] = c2; - c2 = fabs(d[i + 4] - d[i + 3]) + fabs(d[i + 2] - d[i + 1]); - c2 += 0.5*fabs(d[i + 4] + d[i + 3]) + 0.5*fabs(d[i + 2] + d[i + 1]); - if (c2 > 0) { - const double a = (fabs(d[i + 2] - d[i + 1]) + 0.5*fabs(d[i + 2] + d[i + 1]))/c2; - c2 = (1 - a)*d[i + 2] + a*d[i + 3]; - } - else { - c2 = 0; - } - c[1] = (3*d[i + 2] - 2*c[2] - c2)/dx; - c[0] = (c[2] + c2 - 2*d[i + 2])/(dx*dx); - /* No need to store the absolute term y0 */ - /* c[3] = TABLE(i, cols[col] - 1); */ - } - } - - free(d); - return spline; -} - -static CubicHermite1D* fritschButlandSpline1DInit(_In_ const double* table, - size_t nRow, size_t nCol, - _In_ const int* cols, - size_t nCols) { - /* Reference: - - Frederick N. Fritsch and Judy Butland. A method for constructing local - monotone piecewise cubic interpolants. SIAM Journal on Scientific and - Statistical Computing, 5(2), 300-304, June 1984. - (https://dx.doi.org/10.1137/0905021) - */ - - CubicHermite1D* spline; - double* d; /* Divided differences */ - size_t col; - - /* Actually there is no need for consecutive memory */ - spline = (CubicHermite1D*)malloc((nRow - 1)*nCols*sizeof(CubicHermite1D)); - if (NULL == spline) { - return NULL; - } - - d = (double*)malloc((nRow - 1)*sizeof(double)); - if (NULL == d) { - free(spline); - return NULL; - } - - for (col = 0; col < nCols; col++) { - size_t i; - double c2; - - /* Calculation of the divided differences */ - for (i = 0; i < nRow - 1; i++) { - size_t c = (size_t)(cols[col] - 1); - d[i] = (TABLE(i + 1, c) - TABLE(i, c))/ - (TABLE_COL0(i + 1) - TABLE_COL0(i)); - } - - /* Initialization of the left boundary slope */ - c2 = d[0]; - - /* Calculation of the 3(4) coefficients per interval */ - for (i = 0; i < nRow - 1; i++) { - const double dx = TABLE_COL0(i + 1) - TABLE_COL0(i); - double* c = spline[IDX(i, col, nCols)]; - - c[2] = c2; - if (i == nRow - 2) { - c2 = d[nRow - 2]; - } - else if (d[i] == 0 || d[i + 1] == 0 || - (d[i] < 0 && d[i + 1] > 0) || (d[i] > 0 && d[i + 1] < 0)) { - c2 = 0; - } - else { - const double dx_ = TABLE_COL0(i + 2) - TABLE_COL0(i + 1); - c2 = 3*(dx + dx_)/((dx + 2*dx_)/d[i] + (dx_ + 2*dx)/d[i + 1]); - } - c[1] = (3*d[i] - 2*c[2] - c2)/dx; - c[0] = (c[2] + c2 - 2*d[i])/(dx*dx); - /* No need to store the absolute term y0 */ - /* c[3] = TABLE(i, cols[col] - 1); */ - } - } - - free(d); - return spline; -} - -static CubicHermite1D* steffenSpline1DInit(_In_ const double* table, - size_t nRow, size_t nCol, - _In_ const int* cols, - size_t nCols) { - /* Reference: - - Matthias Steffen. A simple method for monotonic interpolation in one - dimension. Astronomy and Astrophysics, 239, 443-450, Nov. 1990. - (https://ui.adsabs.harvard.edu/#abs/1990A&A...239..443S) - */ - - CubicHermite1D* spline; - double* d; /* Divided differences */ - size_t col; - - /* Actually there is no need for consecutive memory */ - spline = (CubicHermite1D*)malloc((nRow - 1)*nCols*sizeof(CubicHermite1D)); - if (NULL == spline) { - return NULL; - } - - d = (double*)malloc((nRow - 1)*sizeof(double)); - if (NULL == d) { - free(spline); - return NULL; - } - - for (col = 0; col < nCols; col++) { - size_t i; - double c2; - - /* Calculation of the divided differences */ - for (i = 0; i < nRow - 1; i++) { - size_t c = (size_t)(cols[col] - 1); - d[i] = (TABLE(i + 1, c) - TABLE(i, c))/ - (TABLE_COL0(i + 1) - TABLE_COL0(i)); - } - - /* Initialization of the left boundary slope */ - c2 = d[0]; - - /* Calculation of the 3(4) coefficients per interval */ - for (i = 0; i < nRow - 1; i++) { - const double dx = TABLE_COL0(i + 1) - TABLE_COL0(i); - double* c = spline[IDX(i, col, nCols)]; - - c[2] = c2; - if (i == nRow - 2) { - c2 = d[nRow - 2]; - } - else if (d[i] == 0 || d[i + 1] == 0 || - (d[i] < 0 && d[i + 1] > 0) || (d[i] > 0 && d[i + 1] < 0)) { - c2 = 0; - } - else { - const double dx_ = TABLE_COL0(i + 2) - TABLE_COL0(i + 1); - double half_abs_c2, abs_di, abs_di1; - c2 = (d[i]*dx_ + d[i + 1]*dx)/(dx + dx_); - half_abs_c2 = 0.5*fabs(c2); - abs_di = fabs(d[i]); - abs_di1 = fabs(d[i + 1]); - if (half_abs_c2 > abs_di || half_abs_c2 > abs_di1) { - const double two_a = d[i] > 0 ? 2 : -2; - c2 = two_a*(abs_di < abs_di1 ? abs_di : abs_di1); - } - } - c[1] = (3*d[i] - 2*c[2] - c2)/dx; - c[0] = (c[2] + c2 - 2*d[i])/(dx*dx); - /* No need to store the absolute term y0 */ - /* c[3] = TABLE(i, cols[col] - 1); */ - } - } - - free(d); - return spline; -} - -static void spline1DClose(CubicHermite1D** spline) { - if (NULL != spline && NULL != *spline) { - free(*spline); - *spline = NULL; - } -} - -/* ----- Internal bivariate spline functions ---- */ - -static void spline1DExtrapolateLeft(double x1, double x2, double x3, double x4, - double x5, double* y1, double* y2, - double y3, double y4, double y5) { - const double a = x4 - x5; - const double b = x3 - x4; - const double c = x2 - x3; - - if (a == 0. || b == 0. || c == 0.) { - *y2 = y3; - *y1 = y3; - } - else { - const double d = x1 - x2; - const double e = y4 - y5; - const double f = y3 - y4; - *y2 = c*(2*f/b - e/a) + y3; - *y1 = *y2 + d*((*y2 - y3)/c + f/b - e/a); - } -} - -static void spline1DExtrapolateRight(double x1, double x2, double x3, double x4, - double x5, double y1, double y2, double y3, - double* y4, double* y5) { - const double a = x2 - x1; - const double b = x3 - x2; - const double c = x4 - x3; - - if (a == 0. || b == 0. || c == 0.) { - *y4 = y3; - *y5 = y3; - } - else { - const double d = x5 - x4; - const double e = y2 - y1; - const double f = y3 - y2; - *y4 = c*(2*f/b - e/a) + y3; - *y5 = *y4 + d*((*y4 - y3)/c + f/b - e/a); - } -} - -static CubicHermite2D* spline2DInit(_In_ const double* table, size_t nRow, - size_t nCol) { - /* Reference: - - Hiroshi Akima. A method of bivariate interpolation and smooth surface - fitting based on local procedures. Communications of the ACM, 17(1), 18-20, - Jan. 1974. (http://dx.doi.org/10.1145/360767.360779) - */ - -#define TABLE_EX(i, j) tableEx[IDX(i, j, nCol + 3)] - CubicHermite2D* spline = NULL; - if (nRow == 2 /* && nCol > 3 */) { - CubicHermite1D* spline1D; - size_t j; - int cols = 2; - - /* Need to transpose */ - double* tableT = (double*)malloc(2*(nCol - 1)*sizeof(double)); - if (NULL == tableT) { - return NULL; - } - - spline = (CubicHermite2D*)malloc((nCol - 1)*sizeof(CubicHermite2D)); - if (NULL == spline) { - free(tableT); - return NULL; - } - - for (j = 1; j < nCol; j++) { - tableT[IDX(j - 1, 0, 2)] = TABLE_ROW0(j); - tableT[IDX(j - 1, 1, 2)] = TABLE(1, j); - } - - spline1D = akimaSpline1DInit(tableT, nCol - 1, 2, &cols, 1); - free(tableT); - if (NULL == spline1D) { - free(spline); - return NULL; - } - /* Copy coefficients */ - for (j = 0; j < nCol - 1; j++) { - const double* c1 = spline1D[j]; - double* c2 = spline[j]; - c2[0] = c1[0]; - c2[1] = c1[1]; - c2[2] = c1[2]; - } - spline1DClose(&spline1D); - } - else if (/*nRow > 3 && */ nCol == 2) { - CubicHermite1D* spline1D; - size_t i; - int cols = 2; - - spline = (CubicHermite2D*)malloc((nRow - 1)*sizeof(CubicHermite2D)); - if (NULL == spline) { - return NULL; - } - - spline1D = akimaSpline1DInit(&table[2], nRow - 1, 2, &cols, 1); - if (NULL == spline1D) { - free(spline); - return NULL; - } - /* Copy coefficients */ - for (i = 0; i < nRow - 1; i++) { - const double* c1 = spline1D[i]; - double* c2 = spline[i]; - c2[0] = c1[0]; - c2[1] = c1[1]; - c2[2] = c1[2]; - } - spline1DClose(&spline1D); - } - else /* if (nRow > 2 && nCol > 2) */ { - size_t i, j; - double* dz_dx; - double* dz_dy; - double* d2z_dxdy; - double* tableEx; - double* x; - double* y; - - /* This is not the most memory efficient implementation since the table - memory is temporarily doubled for the sake of a clean calculation of - the partial derivatives without special consideration of the boundary - regions. - */ - - /* Copy of x coordinates with extrapolated boundary coordinates */ - x = (double*)malloc((nRow + 3)*sizeof(double)); - if (NULL == x) { - return NULL; - } - if (nRow == 3) { - /* Linear extrapolation */ - x[0] = 3*TABLE_COL0(1) - 2*TABLE_COL0(2); - x[1] = 2*TABLE_COL0(1) - TABLE_COL0(2); - x[2] = TABLE_COL0(1); - x[3] = TABLE_COL0(2); - x[4] = 2*TABLE_COL0(2) - TABLE_COL0(1); - x[5] = 3*TABLE_COL0(2) - 2*TABLE_COL0(1); - } - else { - x[0] = 2*TABLE_COL0(1) - TABLE_COL0(3); - x[1] = TABLE_COL0(1) + TABLE_COL0(2) - TABLE_COL0(3); - for (i = 1; i < nRow; i++) { - x[i + 1] = TABLE_COL0(i); - } - x[nRow + 1] = TABLE_COL0(nRow - 1) + - TABLE_COL0(nRow - 2) - TABLE_COL0(nRow - 3); - x[nRow + 2] = 2*TABLE_COL0(nRow - 1) - TABLE_COL0(nRow - 3); - } - - /* Copy of y coordinates with extrapolated boundary coordinates */ - y = (double*)malloc((nCol + 3)*sizeof(double)); - if (NULL == y) { - free(x); - return NULL; - } - if (nCol == 3) { - /* Linear extrapolation */ - y[0] = 3*TABLE_ROW0(1) - 2*TABLE_ROW0(2); - y[1] = 2*TABLE_ROW0(1) - TABLE_ROW0(2); - y[2] = TABLE_ROW0(1); - y[3] = TABLE_ROW0(2); - y[4] = 2*TABLE_ROW0(2) - TABLE_ROW0(1); - y[5] = 3*TABLE_ROW0(2) - 2*TABLE_ROW0(1); - } - else { - y[0] = 2*TABLE_ROW0(1) - TABLE_ROW0(3); - y[1] = TABLE_ROW0(1) + TABLE_ROW0(2) - TABLE_ROW0(3); - memcpy(&y[2], &TABLE_ROW0(1), (nCol - 1)*sizeof(double)); - y[nCol + 1] = TABLE_ROW0(nCol - 1) + - TABLE_ROW0(nCol - 2) - TABLE_ROW0(nCol - 3); - y[nCol + 2] = 2*TABLE_ROW0(nCol - 1) - TABLE_ROW0(nCol - 3); - } - - /* Copy of table with extrapolated boundary values */ - tableEx = (double*)malloc((nRow + 3)*(nCol + 3)*sizeof(double)); - if (NULL == tableEx) { - free(y); - free(x); - return NULL; - } - for (i = 1; i < nRow; i++) { - /* Copy table row */ - memcpy(&TABLE_EX(i + 1, 2), &TABLE(i, 1), (nCol - 1)*sizeof(double)); - } - if (nCol == 3) { - /* Linear extrapolation in y direction */ - for (i = 1; i < nRow; i++) { - TABLE_EX(i + 1, 0) = 3*TABLE(i, 1) - 2*TABLE(i, 2); - TABLE_EX(i + 1, 1) = 2*TABLE(i, 1) - TABLE(i, 2); - TABLE_EX(i + 1, 4) = 2*TABLE(i, 2) - TABLE(i, 1); - TABLE_EX(i + 1, 5) = 3*TABLE(i, 2) - 2*TABLE(i, 1); - } - } - else { - for (i = 1; i < nRow; i++) { - /* Extrapolate table data in y direction */ - spline1DExtrapolateLeft(y[0], y[1], y[2], y[3], y[4], - &TABLE_EX(i + 1, 0), &TABLE_EX(i + 1, 1), TABLE_EX(i + 1, 2), - TABLE_EX(i + 1, 3), TABLE_EX(i + 1, 4)); - spline1DExtrapolateRight(y[nCol - 2], y[nCol - 1], y[nCol], - y[nCol + 1], y[nCol + 2], TABLE_EX(i + 1, nCol - 2), - TABLE_EX(i + 1, nCol - 1), TABLE_EX(i + 1, nCol), - &TABLE_EX(i + 1, nCol + 1), &TABLE_EX(i + 1, nCol + 2)); - } - } - if (nRow == 3) { - /* Linear extrapolation in x direction */ - for (j = 0; j < nCol + 3; j++) { - TABLE_EX(0, j) = 3*TABLE_EX(2, j) - 2*TABLE_EX(3, j); - TABLE_EX(1, j) = 2*TABLE_EX(2, j) - TABLE_EX(3, j); - TABLE_EX(4, j) = 2*TABLE_EX(3, j) - TABLE_EX(2, j); - TABLE_EX(5, j) = 3*TABLE_EX(3, j) - 2*TABLE_EX(2, j); - } - } - else { - for (j = 0; j < nCol + 3; j++) { - /* Extrapolate table data in x direction */ - spline1DExtrapolateLeft(x[0], x[1], x[2], x[3], x[4], - &TABLE_EX(0, j), &TABLE_EX(1, j), TABLE_EX(2, j), - TABLE_EX(3, j), TABLE_EX(4, j)); - spline1DExtrapolateRight(x[nRow - 2], x[nRow - 1], x[nRow], - x[nRow + 1], x[nRow + 2], TABLE_EX(nRow - 2, j), - TABLE_EX(nRow - 1, j), TABLE_EX(nRow, j), - &TABLE_EX(nRow + 1, j), &TABLE_EX(nRow + 2, j)); - } - } - - dz_dx = (double*)malloc((nRow - 1)*(nCol - 1)*sizeof(double)); - if (NULL == dz_dx) { - free(tableEx); - free(y); - free(x); - return NULL; - } - - dz_dy = (double*)malloc((nRow - 1)*(nCol - 1)*sizeof(double)); - if (NULL == dz_dy) { - free(dz_dx); - free(tableEx); - free(y); - free(x); - return NULL; - } - - d2z_dxdy = (double*)malloc((nRow - 1)*(nCol - 1)*sizeof(double)); - if (NULL == d2z_dxdy) { - free(dz_dy); - free(dz_dx); - free(tableEx); - free(y); - free(x); - return NULL; - } - - /* Calculation of the partial derivatives */ - for (i = 2; i < nRow + 1; i++) { - for (j = 2; j < nCol + 1; j++) { - /* Divided differences */ - double d31, d32, d33, d34, d22, d23, d42, d43; - /* Weights */ - double wx2, wx3, wy2, wy3; - - /* Partial derivatives in x direction */ - d31 = (TABLE_EX(i - 1, j) - TABLE_EX(i - 2, j))/ - (x[i - 1] - x[i - 2]); /* = c13 */ - d32 = (TABLE_EX(i, j) - TABLE_EX(i - 1, j))/ - (x[i] - x[i - 1]); /* = c23 */ - d33 = (TABLE_EX(i + 1, j) - TABLE_EX(i, j))/ - (x[i + 1] - x[i]); /* = c33 */ - d34 = (TABLE_EX(i + 2, j) - TABLE_EX(i + 1, j))/ - (x[i + 2] - x[i + 1]); /* = c43 */ - if (d31 == d32 && d33 == d34) { - wx2 = 0.; - wx3 = 0.; - dz_dx[IDX(i - 2, j - 2, nCol - 1)] = 0.5*d32 + 0.5*d33; - } - else { - wx2 = fabs(d34 - d33); - wx3 = fabs(d32 - d31); - dz_dx[IDX(i - 2, j - 2, nCol - 1)] = (wx2*d32 + wx3*d33)/ - (wx2 + wx3); - } - - /* Partial derivatives in y direction */ - d31 = (TABLE_EX(i, j - 1) - TABLE_EX(i, j - 2))/ - (y[j - 1] - y[j - 2]); - d32 = (TABLE_EX(i, j) - TABLE_EX(i, j - 1))/ - (y[j] - y[j - 1]); - d33 = (TABLE_EX(i, j + 1) - TABLE_EX(i, j))/ - (y[j + 1] - y[j]); - d34 = (TABLE_EX(i, j + 2) - TABLE_EX(i, j + 1))/ - (y[j + 2] - y[j + 1]); - if (d31 == d32 && d33 == d34) { - wy2 = 0.; - wy3 = 0.; - dz_dy[IDX(i - 2, j - 2, nCol - 1)] = 0.5*d32 + 0.5*d33; - } - else { - wy2 = fabs(d34 - d33); - wy3 = fabs(d32 - d31); - dz_dy[IDX(i - 2, j - 2, nCol - 1)] = (wy2*d32 + wy3*d33)/ - (wy2 + wy3); - } - - /* Partial cross derivatives */ - d22 = (TABLE_EX(i - 1, j) - TABLE_EX(i - 1, j - 1))/ - (y[j] - y[j - 1]); - d23 = (TABLE_EX(i - 1, j + 1) - TABLE_EX(i - 1, j))/ - (y[j + 1] - y[j]); - d42 = (TABLE_EX(i + 1, j) - TABLE_EX(i + 1, j - 1))/ - (y[j] - y[j - 1]); - d43 = (TABLE_EX(i + 1, j + 1) - TABLE_EX(i + 1, j))/ - (y[j + 1] - y[j]); - d22 = (d32 - d22)/(x[i] - x[i - 1]); /* = e22 */ - d23 = (d33 - d23)/(x[i] - x[i - 1]); /* = e23 */ - d32 = (d42 - d32)/(x[i + 1] - x[i]); /* = e32 */ - d33 = (d43 - d33)/(x[i + 1] - x[i]); /* = e33 */ - if (wx2 == 0. && wx3 == 0.) { - wx2 = 1.; - wx3 = 1.; - } - if (wy2 == 0. && wy3 == 0.) { - wy2 = 1.; - wy3 = 1.; - } - d2z_dxdy[IDX(i - 2, j - 2, nCol - 1)] = - (wx2*(wy2*d22 + wy3*d23) + wx3*(wy2*d32 + wy3*d33))/ - ((wx2 + wx3)*(wy2 + wy3)); - } - } - - free(tableEx); - free(y); - free(x); - - /* Actually there is no need for consecutive memory */ - spline = (CubicHermite2D*)malloc((nRow - 2)*(nCol - 2)*sizeof(CubicHermite2D)); - if (NULL == spline) { - free(dz_dx); - free(dz_dy); - free(d2z_dxdy); - return NULL; - } - - /* Calculation of the 15(16) coefficients per grid */ - for (i = 0; i < nRow - 2; i++) { - const double dx = TABLE_COL0(i + 2) - TABLE_COL0(i + 1); - const double dx_2 = dx*dx; - const double dx_3 = dx_2*dx; - for (j = 0; j < nCol - 2; j++) { - const double z00 = TABLE(i + 1, j + 1); - const double z01 = TABLE(i + 1, j + 2); - const double z10 = TABLE(i + 2, j + 1); - const double z11 = TABLE(i + 2, j + 2); - const double dy = TABLE_ROW0(j + 2) - TABLE_ROW0(j + 1); - const double dy_2 = dy*dy; - const double dy_3 = dy_2*dy; - double zx00, zx01, zx10, zx11; - double zy00, zy01, zy10, zy11; - double zxy00, zxy01, zxy10, zxy11; - double t1, t2, t3, t4, t5, t6, t7, t8, t9; - double t10, t11, t12, t13, t14; - double* c = spline[IDX(i, j, nCol - 2)]; - - c[11] = dz_dx[IDX(i, j, nCol - 1)]; - zx00 = c[11]*dx; - zx01 = dz_dx[IDX(i, j + 1, nCol - 1)]*dx; - zx10 = dz_dx[IDX(i + 1, j, nCol - 1)]*dx; - zx11 = dz_dx[IDX(i + 1, j + 1, nCol - 1)]*dx; - c[14] = dz_dy[IDX(i, j, nCol - 1)]; - zy00 = c[14]*dy; - zy01 = dz_dy[IDX(i, j + 1, nCol - 1)]*dy; - zy10 = dz_dy[IDX(i + 1, j, nCol - 1)]*dy; - zy11 = dz_dy[IDX(i + 1, j + 1, nCol - 1)]*dy; - c[10] = d2z_dxdy[IDX(i, j, nCol - 1)]; - zxy00 = c[10]*dx*dy; - zxy01 = d2z_dxdy[IDX(i, j + 1, nCol - 1)]*dx*dy; - zxy10 = d2z_dxdy[IDX(i + 1, j, nCol - 1)]*dx*dy; - zxy11 = d2z_dxdy[IDX(i + 1, j + 1, nCol - 1)]*dx*dy; - t1 = z00 - z10; - t2 = zx00 + zx10; - t3 = zy00 - zy10; - t4 = zy11 - zy01; - t5 = zxy00 + zxy10; - t6 = zxy11 + zxy01; - t7 = 2*zx00 + zx10; - t8 = 2*zxy00 + zxy10; - t9 = zxy11 + 2*zxy01; - t10 = zx00 - zx01; - t11 = z00 - z01; - t12 = t1 + (z11 - z01); - t13 = t3 - t4; - t4 = 2*t3 - t4; - t14 = 2*t12 + (t2 - (zx11 + zx01)); - t12 = 3*t12 + (t7 - (zx11 + 2*zx01)); - c[0] = (2*t14 + (2*t13 + (t5 + t6)))/(dx_3*dy_3); - c[1] = -(3*t14 + (2*t4 + (2*t5 + t6)))/(dx_3*dy_2); - c[2] = (2*t3 + t5)/(dx_3*dy); - c[3] = (2*t1 + t2)/dx_3; - c[4] = -(2*t12 + (3*t13 + (t8 + t9)))/(dx_2*dy_3); - c[5] = (3*t12 + (3*t4 + (2*t8 + t9)))/(dx_2*dy_2); - c[6] = -(3*t3 + t8)/(dx_2*dy); - c[7] = -(3*t1 + t7)/dx_2; - c[8] = (2*t10 + (zxy00 + zxy01))/(dx*dy_3); - c[9] = -(3*t10 + (2*zxy00 + zxy01))/(dx*dy_2); - c[12] = (2*t11 + (zy00 + zy01))/dy_3; - c[13] = -(3*t11 + (2*zy00 + zy01))/dy_2; - /* No need to store the absolute term z00 */ - /* c[15] = z00; */ - } - } - - free(dz_dx); - free(dz_dy); - free(d2z_dxdy); - } - return spline; -#undef TABLE_EX -} - -static void spline2DClose(CubicHermite2D** spline) { - if (NULL != spline && NULL != *spline) { - free(*spline); - *spline = NULL; - } -} - -static void transpose(_Inout_ double* table, size_t nRow, size_t nCol) { - /* Reference: - - Cycle-based in-place array transposition - (http://en.wikipedia.org/wiki/In-place_matrix_transposition#Non-square_matrices:_Following_the_cycles) - */ - - size_t i; - for (i = 1; i < nRow*nCol - 1; i++) { - size_t x = nRow*(i % nCol) + i/nCol; /* predecessor of i in the cycle */ - /* Continue if cycle is of length one or predecessor already was visited */ - if (x <= i) { - continue; - } - /* Continue if cycle already was visited */ - while (x > i) { - x = nRow*(x % nCol) + x/nCol; - } - if (x < i) { - continue; - } - { - double tmp = table[i]; - size_t s = i; /* start index in the cycle */ - x = nRow*(i % nCol) + i/nCol; /* predecessor of i in the cycle */ - while (x != i) { - table[s] = table[x]; - s = x; - x = nRow*(x % nCol) + x/nCol; - } - table[s] = tmp; - } - } -} - -/* ----- Internal I/O functions ----- */ - -#if defined(TABLE_SHARE) && !defined(NO_FILE_SYSTEM) -static size_t key_strlen(_In_z_ const char *s) { - size_t len = strlen(s) + 1; - len += strlen(s + len); - return len; -} -#endif - -static READ_RESULT readTable(_In_z_ const char* fileName, _In_z_ const char* tableName, - _Inout_ size_t* nRow, _Inout_ size_t* nCol, int verbose, - int force, _In_z_ const char* delimiter, int nHeaderLines) { -#if !defined(NO_FILE_SYSTEM) -#if defined(TABLE_SHARE) - TableShare* file = NULL; -#endif - double* table = NULL; - if (NULL != tableName && NULL != fileName && NULL != nRow && NULL != nCol) { -#if defined(TABLE_SHARE) - size_t lenFileName = strlen(fileName); - char* key = (char*)malloc((lenFileName + strlen(tableName) + 2)*sizeof(char)); - if (NULL != key) { - int updateError = 0; - strcpy(key, fileName); - strcpy(key + lenFileName + 1, tableName); - MUTEX_LOCK(); - HASH_FIND_STR(tableShare, key, file); - if (NULL == file || force) { - /* Release resources since ModelicaIO_readRealTable2 may fail with - ModelicaError - */ - MUTEX_UNLOCK(); - free(key); -#endif - table = ModelicaIO_readRealTable2(fileName, tableName, - nRow, nCol, verbose, delimiter, nHeaderLines); - if (NULL == table) { -#if defined(TABLE_SHARE) - return file; -#else - return table; -#endif - } -#if defined(TABLE_SHARE) - /* Again allocate and set key */ - key = (char*)malloc((lenFileName + strlen(tableName) + 2) * sizeof(char)); - if (NULL == key) { - ModelicaIO_freeRealTable(table); - return file; - } - strcpy(key, fileName); - strcpy(key + lenFileName + 1, tableName); - /* Again ask for lock and search in hash table share */ - MUTEX_LOCK(); - HASH_FIND_STR(tableShare, key, file); - } - if (NULL == file) { - /* Share miss -> Insert new table */ - file = (TableShare*)malloc(sizeof(TableShare)); - if (NULL != file) { - size_t lenKey = key_strlen(key); - file->key = key; - file->refCount = 1; - file->nRow = *nRow; - file->nCol = *nCol; - file->table = table; - HASH_ADD_KEYPTR(hh, tableShare, key, lenKey, file); - if (NULL == file->hh.tbl) { - free(key); - free(file); - ModelicaIO_freeRealTable(table); - MUTEX_UNLOCK(); - return NULL; - } - } - else { - free(key); - ModelicaIO_freeRealTable(table); - MUTEX_UNLOCK(); - return file; - } - } - else if (force) { - /* Share hit -> Update table share (only if not shared - by multiple table objects) - */ - free(key); - if (file->refCount == 1) { - ModelicaIO_freeRealTable(file->table); - file->nRow = *nRow; - file->nCol = *nCol; - file->table = table; - } - else { - updateError = 1; - } - } - else { - /* Share hit -> Read from table share and increment table - reference counter - */ - free(key); - if (NULL != table) { - ModelicaIO_freeRealTable(table); - } - file->refCount++; - *nRow = file->nRow; - *nCol = file->nCol; - } - MUTEX_UNLOCK(); - if (updateError == 1) { - ModelicaFormatError("Not possible to update shared " - "table \"%s\" from \"%s\": File and table name " - "must be unique.\n", tableName, fileName); - } - } -#endif - } -#if defined(TABLE_SHARE) - return file; -#else - return table; -#endif -#else - return NULL; -#endif /* #if !defined(NO_FILE_SYSTEM) */ -} - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif diff --git a/ModelicaExternalC/C-Sources/ModelicaStandardTables.h b/ModelicaExternalC/C-Sources/ModelicaStandardTables.h deleted file mode 100644 index 90b44498d..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaStandardTables.h +++ /dev/null @@ -1,499 +0,0 @@ -/* ModelicaStandardTables.h - External table functions header - - Copyright (C) 2008-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* The following #define's are available. - - NO_FILE_SYSTEM : A file system is not present (e.g. on dSPACE or xPC). - NO_MUTEX : Pthread mutex is not present (e.g. on dSPACE) - NO_TABLE_COPY : Do not copy table data passed to _init functions - This is a potentially unsafe optimization (ticket #1143). - TABLE_SHARE : If NO_FILE_SYTEM is not defined then common/shared table - arrays are stored in a global hash table in order to - avoid superfluous file input access and to decrease the - utilized memory (tickets #1110 and #1550). - DEBUG_TIME_EVENTS : Trace time events of CombiTimeTable - DUMMY_FUNCTION_USERTAB: Use a dummy function "usertab" - - Changelog: - Dec. 22, 2020: by Thomas Beutlich - Added reading of CSV files (ticket #1153) - - Aug. 03, 2019: by Thomas Beutlich - Added second derivatives (ticket #2901) - - Apr. 24, 2017: by Thomas Beutlich, ESI ITI GmbH - Added functions to retrieve minimum and maximum abscissa - values of CombiTable2D (ticket #2244) - - Apr. 15, 2017: by Thomas Beutlich, ESI ITI GmbH - Added support for time event generation (independent of - smoothness) in CombiTimeTable (ticket #2080) - - Apr. 11, 2017: by Thomas Beutlich, ESI ITI GmbH - Revised initialization of CombiTimeTable, CombiTable1D - and CombiTable2D (ticket #1899) - - Already read table in the initialization functions - - Removed the implementation of the read functions - - Apr. 07, 2017: by Thomas Beutlich, ESI ITI GmbH - Added support for shift time (independent of start time) - in CombiTimeTable (ticket #1771) - - Feb. 25, 2017: by Thomas Beutlich, ESI ITI GmbH - Added support for extrapolation in CombiTable1D (ticket #1839) - Added functions to retrieve minimum and maximum abscissa - values of CombiTable1D (ticket #2120) - - Oct. 27, 2015: by Thomas Beutlich, ITI GmbH - Added nonnull attribute/annotations (ticket #1436) - - Apr. 09, 2013: by Thomas Beutlich, ITI GmbH - Revised the first version - - Jan. 27, 2008: by Martin Otter, DLR - Implemented a first version -*/ - -/* A table can be defined in the following ways when initializing the table: - - (1) Explicitly supplied in the argument list - (= table is "NoName" or has only blanks AND - fileName is "NoName" or has only blanks). - - (2) Read from a file (fileName, tableName have to be supplied). - - Tables may be linearly interpolated or the first derivative - may be continuous. In the latter case, cubic Hermite splines with Akima slope - approximation, Fritsch-Butland slope approximation (univariate only) or Steffen - slope approximation (univariate only) are used. -*/ - -#ifndef MODELICA_STANDARDTABLES_H_ -#define MODELICA_STANDARDTABLES_H_ - -#include - -#if !defined(MODELICA_EXPORT) -#if defined(__cplusplus) -#define MODELICA_EXPORT extern "C" -#else -#define MODELICA_EXPORT -#endif -#endif - -/* - * Non-null pointers and esp. null-terminated strings need to be passed to - * external functions. - * - * The following macros handle nonnull attributes for GNU C and Microsoft SAL. - */ -#undef MODELICA_NONNULLATTR -#if defined(__GNUC__) -#define MODELICA_NONNULLATTR __attribute__((nonnull)) -#else -#define MODELICA_NONNULLATTR -#endif -#if !defined(__ATTR_SAL) -#undef _In_ -#undef _In_z_ -#undef _Inout_ -#define _In_ -#define _In_z_ -#define _Inout_ -#endif - -MODELICA_EXPORT void* ModelicaStandardTables_CombiTimeTable_init(_In_z_ const char* tableName, - _In_z_ const char* fileName, - _In_ double* table, size_t nRow, - size_t nColumn, - double startTime, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation) MODELICA_NONNULLATTR; - /* Same as ModelicaStandardTables_CombiTimeTable_init2, but without shiftTime, timeEvents and - verbose arguments - */ - -MODELICA_EXPORT void* ModelicaStandardTables_CombiTimeTable_init2(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, - double startTime, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation, - double shiftTime, - int timeEvents, - int verbose) MODELICA_NONNULLATTR; - /* Same as ModelicaStandardTables_CombiTimeTable_init3, but without delimiter and nHeaderLines - arguments - */ - -MODELICA_EXPORT void* ModelicaStandardTables_CombiTimeTable_init3(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, - double startTime, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation, - double shiftTime, - int timeEvents, - int verbose, - _In_z_ const char* delimiter, - int nHeaderLines) MODELICA_NONNULLATTR; - /* Initialize 1-dim. table where first column is time - - -> fileName: Name of file - -> tableName: Name of table - -> table: If tableName="NoName" or has only blanks AND - fileName ="NoName" or has only blanks, then - this pointer points to a 2-dim. array (row-wise storage) - in the Modelica environment that holds this matrix. - -> nRow: Number of rows of table - -> nColumn: Number of columns of table - -> startTime: Start time of inter-/extrapolation - -> columns: Columns of table to be interpolated - -> nCols: Number of columns of table to be interpolated - -> smoothness: Interpolation type - = 1: linear - = 2: continuous first derivative (by Akima splines) - = 3: constant - = 4: monotonicity-preserving, continuous first derivative - (by Fritsch-Butland splines) - = 5: monotonicity-preserving, continuous first derivative - (by Steffen splines) - -> extrapolation: Extrapolation type - = 1: hold first/last value - = 2: linear - = 3: periodic - = 4: no - -> shiftTime: Shift time of first table column - -> timeEvents: Time event handling (for constant or linear interpolation) - = 1: always - = 2: at discontinuities - = 3: no - -> verbose: Print message that file is loading - -> delimiter: Column delimiter character (CSV file only) - -> nHeaderLines: Number of header lines to ignore (CSV file only) - <- RETURN: Pointer to internal memory of table structure - */ - -MODELICA_EXPORT void ModelicaStandardTables_CombiTimeTable_close(void* tableID); - /* Close table and free allocated memory */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_minimumTime(void* tableID); - /* Return minimum abscissa defined in table (= table[1,1]) */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_maximumTime(void* tableID); - /* Return maximum abscissa defined in table (= table[end,1]) */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_getValue(void* tableID, - int icol, double t, - double nextTimeEvent, - double preNextTimeEvent); - /* Interpolate in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTimeTable_init - -> icol: Index (1-based) of column to interpolate - -> t: Abscissa value (time) - -> nextTimeEvent: Next time event (found by ModelicaStandardTables_CombiTimeTable_nextTimeEvent) - -> preNextTimeEvent: Pre value of next time event - <- RETURN : Ordinate value - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_getDerValue(void* tableID, - int icol, - double t, - double nextTimeEvent, - double preNextTimeEvent, - double der_t); - /* Interpolated derivative in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTimeTable_init - -> icol: Index (1-based) of column to interpolate - -> t: Abscissa value (time) - -> nextTimeEvent: Next time event (found by ModelicaStandardTables_CombiTimeTable_nextTimeEvent) - -> preNextTimeEvent: Pre value of next time event - -> der_t: Derivative of abscissa value (time) - <- RETURN: Derivative of ordinate value - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_getDer2Value(void* tableID, - int icol, - double t, - double nextTimeEvent, - double preNextTimeEvent, - double der_t, - double der2_t); - /* Interpolated second derivative in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTimeTable_init - -> icol: Index (1-based) of column to interpolate - -> t: Abscissa value (time) - -> nextTimeEvent: Next time event (found by ModelicaStandardTables_CombiTimeTable_nextTimeEvent) - -> preNextTimeEvent: Pre value of next time event - -> der_t: Derivative of abscissa value (time) - -> der2_t: Second derivative of abscissa value (time) - <- RETURN: Second derivative of ordinate value - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_nextTimeEvent(void* tableID, double t); - /* Return next time event in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTimeTable_init - -> t: Abscissa value (time) - <- RETURN: Next abscissa value > t that triggers a time event - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTimeTable_read(void* tableID, int force, - int verbose); - /* Empty function, kept only for backward compatibility */ - -MODELICA_EXPORT void* ModelicaStandardTables_CombiTable1D_init(_In_z_ const char* tableName, - _In_z_ const char* fileName, - _In_ double* table, size_t nRow, - size_t nColumn, - _In_ int* columns, - size_t nCols, int smoothness) MODELICA_NONNULLATTR; - /* Same as ModelicaStandardTables_CombiTable1D_init2, but without extrapolation and - verbose arguments - */ - -MODELICA_EXPORT void* ModelicaStandardTables_CombiTable1D_init2(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation, - int verbose) MODELICA_NONNULLATTR; - /* Same as ModelicaStandardTables_CombiTable1D_init3, but without delimiter and nHeaderLines - arguments - */ - -MODELICA_EXPORT void* ModelicaStandardTables_CombiTable1D_init3(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, - _In_ int* columns, - size_t nCols, int smoothness, - int extrapolation, - int verbose, - _In_z_ const char* delimiter, - int nHeaderLines) MODELICA_NONNULLATTR; - /* Initialize 1-dim. table defined by matrix, where first column - is x-axis and further columns of matrix are interpolated - - -> fileName: Name of file - -> tableName: Name of table - -> table: If tableName="NoName" or has only blanks AND - fileName ="NoName" or has only blanks, then - this pointer points to a 2-dim. array (row-wise storage) - in the Modelica environment that holds this matrix. - -> nRow: Number of rows of table - -> nColumn: Number of columns of table - -> columns: Columns of table to be interpolated - -> nCols: Number of columns of table to be interpolated - -> smoothness: Interpolation type - = 1: linear - = 2: continuous first derivative (by Akima splines) - = 3: constant - = 4: monotonicity-preserving, continuous first derivative - (by Fritsch-Butland splines) - = 5: monotonicity-preserving, continuous first derivative - (by Steffen splines) - -> extrapolation: Extrapolation type - = 1: hold first/last value - = 2: linear - = 3: periodic - = 4: no - -> verbose: Print message that file is loading - -> delimiter: Column delimiter character (CSV file only) - -> nHeaderLines: Number of header lines to ignore (CSV file only) - <- RETURN: Pointer to internal memory of table structure - */ - -MODELICA_EXPORT void ModelicaStandardTables_CombiTable1D_close(void* tableID); - /* Close table and free allocated memory */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable1D_minimumAbscissa(void* tableID); - /* Return minimum abscissa defined in table (= table[1,1]) */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable1D_maximumAbscissa(void* tableID); - /* Return maximum abscissa defined in table (= table[end,1]) */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable1D_getValue(void* tableID, int icol, - double u); - /* Interpolate in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTable1D_init - -> icol: Index (1-based) of column to interpolate - -> u: Abscissa value - <- RETURN : Ordinate value - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable1D_getDerValue(void* tableID, int icol, - double u, double der_u); - /* Interpolated derivative in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTable1D_init - -> icol: Index (1-based) of column to interpolate - -> u: Abscissa value - -> der_u: Derivative of abscissa value - <- RETURN: Derivative of ordinate value - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable1D_getDer2Value(void* tableID, int icol, - double u, double der_u, double der2_u); - /* Interpolated second derivative in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTable1D_init - -> icol: Index (1-based) of column to interpolate - -> u: Abscissa value - -> der_u: Derivative of abscissa value - -> der2_u: Second derivative of abscissa value - <- RETURN: Second derivative of ordinate value - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable1D_read(void* tableID, int force, - int verbose); - /* Empty function, kept only for backward compatibility */ - -MODELICA_EXPORT void* ModelicaStandardTables_CombiTable2D_init(_In_z_ const char* tableName, - _In_z_ const char* fileName, - _In_ double* table, size_t nRow, - size_t nColumn, int smoothness) MODELICA_NONNULLATTR; - /* Same as ModelicaStandardTables_CombiTable2D_init2, but without verbose argument */ - -MODELICA_EXPORT void* ModelicaStandardTables_CombiTable2D_init2(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, int smoothness, - int extrapolation, - int verbose) MODELICA_NONNULLATTR; - /* Same as ModelicaStandardTables_CombiTable2D_init3, but without delimiter and nHeaderLines - arguments - */ - -MODELICA_EXPORT void* ModelicaStandardTables_CombiTable2D_init3(_In_z_ const char* fileName, - _In_z_ const char* tableName, - _In_ double* table, size_t nRow, - size_t nColumn, int smoothness, - int extrapolation, - int verbose, - _In_z_ const char* delimiter, - int nHeaderLines) MODELICA_NONNULLATTR; - /* Initialize 2-dim. table defined by matrix, where first column - is x-axis, first row is y-axis and the matrix elements are the - z-values. - table[2:end,1 ]: Values of x-axis - [1 ,2:end]: Values of y-axis - [2:end,2:end]: Values of z-axis - - -> tableName: Name of table - -> fileName: Name of file - -> table: If tableName="NoName" or has only blanks AND - fileName ="NoName" or has only blanks, then - this pointer points to a 2-dim. array (row-wise storage) - in the Modelica environment that holds this matrix. - -> nRow: Number of rows of table - -> nColumn: Number of columns of table - -> smoothness: Interpolation type - = 1: bilinear - = 2: continuous first derivative (by bivariate Akima splines) - = 3: bivariate constant - -> extrapolation: Extrapolation type - = 1: hold first/last value - = 2: linear - = 3: periodic - = 4: no - -> verbose: Print message that file is loading - -> delimiter: Column delimiter character (CSV file only) - -> nHeaderLines: Number of header lines to ignore (CSV file only) - <- RETURN: Pointer to internal memory of table structure - */ - -MODELICA_EXPORT void ModelicaStandardTables_CombiTable2D_close(void* tableID); - /* Close table and free allocated memory */ - -MODELICA_EXPORT void ModelicaStandardTables_CombiTable2D_minimumAbscissa(void* tableID, - _Inout_ double* uMin); - /* Get minimum abscissa defined in table (= table[2,1] and table[1,2]) */ - -MODELICA_EXPORT void ModelicaStandardTables_CombiTable2D_maximumAbscissa(void* tableID, - _Inout_ double* uMax); - /* Get maximum abscissa defined in table (= table[end,1] and table[1,end]) */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable2D_getValue(void* tableID, double u1, - double u2); - /* Interpolate in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTable2D_init - -> u1: Value of first independent variable - -> u2: Value of second independent variable - <- RETURN : Interpolated value - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable2D_getDerValue(void* tableID, double u1, - double u2, double der_u1, - double der_u2); - /* Interpolated derivative in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTable2D_init - -> u1: Value of first independent variable - -> u2: Value of second independent variable - -> der_u1: Derivative value of first independent variable - -> der_u2: Derivative value of second independent variable - <- RETURN: Derivative of interpolated value - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable2D_getDer2Value(void* tableID, double u1, - double u2, double der_u1, - double der_u2, double der2_u1, - double der2_u2); - /* Interpolated second derivative in table - - -> tableID: Pointer to table defined with ModelicaStandardTables_CombiTable2D_init - -> u1: Value of first independent variable - -> u2: Value of second independent variable - -> der_u1: Derivative value of first independent variable - -> der_u2: Derivative value of second independent variable - -> der2_u1: Second derivative value of first independent variable - -> der2_u2: Second derivative value of second independent variable - <- RETURN: Second derivative of interpolated value - */ - -MODELICA_EXPORT double ModelicaStandardTables_CombiTable2D_read(void* tableID, int force, - int verbose); - /* Empty function, kept only for backward compatibility */ - -#endif diff --git a/ModelicaExternalC/C-Sources/ModelicaStandardTablesUsertab.c b/ModelicaExternalC/C-Sources/ModelicaStandardTablesUsertab.c deleted file mode 100644 index a604e5faf..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaStandardTablesUsertab.c +++ /dev/null @@ -1,63 +0,0 @@ -/* ModelicaStandardTablesUsertab.c - A dummy usertab function - - Copyright (C) 2013-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* The usertab function needs to be in a separate object or clang/gcc - optimize the code in such a way that the user-defined usertab gets - sent the wrong input. - - NOTE: If a dummy usertab is included in your code, you may be unable - to also provide a user-defined usertab. If you use dynamic linking - this is sometimes possible: when the simulation executable provides - a usertab object, it will be part of the table of loaded objects and - when later loading the shared object version of ModelicaStandardTables, - the dummy usertab will not be loaded by the dynamic linker; this is - what can confuse C-compilers and why this function is in a separate - file). - - The interface of usertab is defined in ModelicaStandardTables.c - */ - -#include "ModelicaUtilities.h" - -#if defined(DUMMY_FUNCTION_USERTAB) -#if (defined(__clang__) || defined(__GNUC__)) && !(defined(__apple_build_version__) || defined(__APPLE__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__)) -int usertab(char* tableName, int nipo, int dim[], int* colWise, - double** table) __attribute__ ((weak, alias ("dummy_usertab"))); -#define USERTAB_NAME dummy_usertab -#else -#define USERTAB_NAME usertab -#endif /* clang/gcc weak linking */ -int USERTAB_NAME(char* tableName, int nipo, int dim[], int* colWise, - double** table) { - ModelicaError("Function \"usertab\" is not implemented\n"); - return 1; /* Error */ -} -#endif /* #if defined(DUMMY_FUNCTION_USERTAB) */ diff --git a/ModelicaExternalC/C-Sources/ModelicaStrings.c b/ModelicaExternalC/C-Sources/ModelicaStrings.c deleted file mode 100644 index 02e1ae041..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaStrings.c +++ /dev/null @@ -1,540 +0,0 @@ -/* ModelicaStrings.c - External functions for Modelica.Utilities.Strings - - Copyright (C) 2002-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* Changelog: - Mar. 15, 2020: by Thomas Beutlich - Improved fault-tolerance of ModelicaStrings_substring w.r.t. - index arguments (ticket #3503) - - Jun. 16, 2017: by Thomas Beutlich, ESI ITI GmbH - Utilized hash macros of uthash.h for ModelicaStrings_hashString - (ticket #2250) - - Nov. 23, 2016: by Martin Sjoelund, SICS East Swedish ICT AB - Added NO_LOCALE define flag, in case the OS does - not have this (for example when using GCC compiler, - but not libc). Also added autoconf detection for - this flag, NO_PID, NO_TIME, and NO_FILE_SYSTEM - - Feb. 26, 2016: by Hans Olsson, DS AB - Build hash code on the unsigned characters in - ModelicaStrings_hashString (ticket #1926) - - Oct. 27, 2015: by Thomas Beutlich, ITI GmbH - Added nonnull attributes/annotations (ticket #1436) - - Oct. 05, 2015: by Thomas Beutlich, ITI GmbH - Added function ModelicaStrings_hashString from ModelicaRandom.c - of https://github.com/DLR-SR/Noise (ticket #1662) - - Mar. 26, 2013: by Martin Otter, DLR - Introduced three (int) casts to avoid warning messages (ticket #1032) - - Jan. 11, 2013: by Jesper Mattsson, Modelon AB - Made code C89 compatible - - Jan. 5, 2013: by Martin Otter, DLR - Removed "static" declarations from the Modelica interface functions - - Sep. 24, 2004: by Martin Otter, DLR - Final cleaning up of the code - - Sep. 9, 2004: by Dag Brueck, Dynasim AB - Implementation of scan functions - - Aug. 19, 2004: by Martin Otter, DLR - Changed according to the decisions of the 37th - design meeting in Lund (see minutes) - - Jan. 7, 2002: by Martin Otter, DLR - Implemented a first version -*/ - -#if defined(__gnu_linux__) -#define _GNU_SOURCE 1 -#endif - -#include "ModelicaStrings.h" - -#include -#include -#if !defined(NO_LOCALE) -#include -#endif - -#include "ModelicaUtilities.h" -#include "stdint_wrap.h" -#define HASH_NO_STDINT 1 -#include "uthash.h" -#undef uthash_fatal /* Ensure that nowhere in this file uses uthash_fatal by accident */ - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wtautological-compare" -#endif - -_Ret_z_ const char* ModelicaStrings_substring(_In_z_ const char* string, - int startIndex, int endIndex) { - /* Return string(startIndex:endIndex) if endIndex >= startIndex, - or return string(startIndex:startIndex), if endIndex < 0. - Warnings are triggered, if startIndex/endIndex are not valid. - */ - char* substring; - int len = ModelicaStrings_length(string); - - /* Check arguments */ - if (startIndex < 1) { - ModelicaFormatWarning("Non-positive startIndex (= %d) of Utilities.Strings.substring " - "was set to 1.\n", startIndex); - startIndex = 1; - } - else if (startIndex > len) { - return ""; - } - if (endIndex < 0) { - ModelicaFormatWarning("Negative endIndex (= %d) of Utilities.Strings.substring " - "was set to %d.\n", endIndex, startIndex); - endIndex = startIndex; - } - else if (endIndex < startIndex) { - return ""; - } - else if (endIndex > len) { - endIndex = len; - } - - /* Allocate memory and copy string */ - len = endIndex - startIndex + 1; - substring = ModelicaAllocateString((size_t)len); - strncpy(substring, &string[startIndex-1], (size_t)len); - substring[len] = '\0'; - return substring; -} - -int ModelicaStrings_length(_In_z_ const char* string) { - /* Return the number of characters "string" */ - return (int) strlen(string); -} - -int ModelicaStrings_compare(_In_z_ const char* string1, _In_z_ const char* string2, int caseSensitive) { - /* Compare two strings, optionally ignoring case */ - int result; - if (string1 == 0 || string2 == 0) { - return 2; - } - - if (caseSensitive) { - result = strcmp(string1, string2); - } - else { - while (tolower((unsigned char)*string1) == tolower((unsigned char)*string2) && *string1 != '\0') { - string1++; - string2++; - } - result = (int)(tolower((unsigned char)*string1)) - (int)(tolower((unsigned char)*string2)); - } - - if (result < 0) { - result = 1; - } - else if (result == 0) { - result = 2; - } - else { - result = 3; - } - return result; -} - -#define MAX_TOKEN_SIZE 100 - -int ModelicaStrings_skipWhiteSpace(_In_z_ const char* string, int i) { - /* Return index in string after skipping ws, or position of terminating nul. */ - while (string[i-1] != '\0' && isspace((unsigned char)string[i-1])) { - ++i; - } - return i; -} - -/* ----------------- utility functions used in scanXXX functions ----------- */ - -static int InSet(const char* string, int i, const char* separators) { - /* Return true if string[i] is one of the characters in separators. */ - return strchr(separators, string[i-1]) != NULL; -} - -static int SkipNonWhiteSpaceSeparator(const char* string, int i, const char* separators) { - /* Return index in string of first character which is ws or character in separators, - or position of terminating nul. - */ - while (string[i-1] != '\0' && (isspace((unsigned char)string[i-1]) || InSet(string, i, separators))) { - ++i; - } - return i; -} - -static int MatchUnsignedInteger(const char* string, int start) { - /* Starts matching character which make an unsigned integer. The matching - begins at the start index (first char has index 1). Returns the number - of characters that could be matched, or zero if the first character - was not a digit. - */ - const char* begin = &string[start-1]; - const char* p = begin; - while (*p != '\0' && isdigit((unsigned char)*p)) { - ++p; - } - return (int) (p - begin); -} - -/* --------------- end of utility functions used in scanXXX functions ----------- */ - -void ModelicaStrings_scanIdentifier(_In_z_ const char* string, - int startIndex, _Out_ int* nextIndex, - _Out_ const char** identifier) { - int token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); - /* Index of first char of token, after ws. */ - - if (isalpha((unsigned char)string[token_start-1])) { - /* Identifier has begun. */ - int token_length = 1; - while (string[token_start+token_length-1] != '\0' && - (isalpha((unsigned char)string[token_start+token_length-1]) || - isdigit((unsigned char)string[token_start+token_length-1]) || - string[token_start+token_length-1] == '_')) { - ++token_length; - } - - { - char* s = ModelicaAllocateString((size_t)token_length); - strncpy(s, string+token_start-1, (size_t)token_length); - s[token_length] = '\0'; - *nextIndex = token_start + token_length; - *identifier = s; - return; - } - } - - /* Token missing or not identifier. */ - *nextIndex = startIndex; - { - char* s = ModelicaAllocateString(0); - s[0] = '\0'; - *identifier = s; - } - return; -} - -void ModelicaStrings_scanInteger(_In_z_ const char* string, - int startIndex, int unsignedNumber, - _Out_ int* nextIndex, _Out_ int* integerNumber) { - int sign = 0; - /* Number of characters used for sign. */ - - int token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); - /* Index of first char of token, after ws. */ - - if (string[token_start-1] == '+' || string[token_start-1] == '-') { - sign = 1; - } - - if (unsignedNumber==0 || (unsignedNumber==1 && sign==0)) { - int number_length = MatchUnsignedInteger(string, token_start + sign); - /* Number of characters in unsigned number. */ - - if (number_length > 0 && sign + number_length < MAX_TOKEN_SIZE) { - /* check if the scanned string is no Real number */ - int next = token_start + sign + number_length - 1; - if ( string[next] == '\0' || - (string[next] != '.' && string[next] != 'e' - && string[next] != 'E') ) { -#if defined(NO_LOCALE) -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - _locale_t loc = _create_locale(LC_NUMERIC, "C"); -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - locale_t loc = newlocale(LC_NUMERIC, "C", NULL); -#endif - char buf[MAX_TOKEN_SIZE+1]; - /* Buffer for copying the part recognized as the number for passing to strtol(). */ - char* endptr; - /* For error checking of strtol(). */ - int x; - /* For receiving the result. */ - - strncpy(buf, string+token_start-1, (size_t)(sign + number_length)); - buf[sign + number_length] = '\0'; -#if !defined(NO_LOCALE) && (defined(_MSC_VER) && _MSC_VER >= 1400) - x = (int)_strtol_l(buf, &endptr, 10, loc); - _free_locale(loc); -#elif !defined(NO_LOCALE) && (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) - x = (int)strtol_l(buf, &endptr, 10, loc); - freelocale(loc); -#else - x = (int)strtol(buf, &endptr, 10); -#endif - if (*endptr == 0) { - *integerNumber = x; - *nextIndex = token_start + sign + number_length; - return; - } - } - } - } - - /* Token missing or cannot be converted to result type. */ - *nextIndex = startIndex; - *integerNumber = 0; - return; -} - -void ModelicaStrings_scanReal(_In_z_ const char* string, int startIndex, - int unsignedNumber, _Out_ int* nextIndex, - _Out_ double* number) { - /* - Grammar of real number: - - real ::= [sign] unsigned [fraction] [exponent] - sign ::= '+' | '-' - unsigned ::= digit [unsigned] - fraction ::= '.' [unsigned] - exponent ::= ('e' | 'E') [sign] unsigned - digit ::= '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' - */ - - int len; - /* Temporary variable for the length of a matched unsigned number. */ - - int total_length = 0; - /* Total number of characters recognized as part of a decimal number. */ - - int token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); - /* Index of first char of token, after ws. */ - - /* Scan sign of decimal number */ - - if (string[token_start-1] == '+' || string[token_start-1] == '-') { - total_length = 1; - if (unsignedNumber == 1) { - goto Modelica_ERROR; - } - } - - /* Scan integer part of mantissa. */ - - len = MatchUnsignedInteger(string, token_start + total_length); - total_length += len; - - /* Scan decimal part of mantissa. */ - - if (string[token_start + total_length-1] == '.') { - total_length += 1; - len = MatchUnsignedInteger(string, token_start + total_length); - if (len > 0) { - total_length += len; - } - } - - /* Scan exponent part of mantissa. */ - - if (string[token_start + total_length-1] == 'e' || string[token_start + total_length-1] == 'E') { - int exp_len = 1; - /* Total number of characters recognized as part of the non-numeric parts - * of exponent (the 'e' and the sign). */ - - if (string[token_start + total_length] == '+' || string[token_start + total_length] == '-') { - exp_len += 1; - } - len = MatchUnsignedInteger(string, token_start + total_length + exp_len); - if (len == 0) { - goto Modelica_ERROR; - } - total_length += exp_len + len; - } - - /* Convert accumulated characters into a number. */ - - if (total_length > 0 && total_length < MAX_TOKEN_SIZE) { -#if defined(NO_LOCALE) - const char* const dec = "."; -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - _locale_t loc = _create_locale(LC_NUMERIC, "C"); -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3) - locale_t loc = newlocale(LC_NUMERIC, "C", NULL); -#else - char* dec = localeconv()->decimal_point; -#endif - char buf[MAX_TOKEN_SIZE+1]; - /* Buffer for copying the part recognized as the number for passing to strtod(). */ - char* endptr; - /* For error checking of strtod(). */ - double x; - /* For receiving the result. */ - - strncpy(buf, string+token_start-1, (size_t)total_length); - buf[total_length] = '\0'; -#if !defined(NO_LOCALE) && (defined(_MSC_VER) && _MSC_VER >= 1400) - x = _strtod_l(buf, &endptr, loc); - _free_locale(loc); -#elif !defined(NO_LOCALE) && (defined(__GLIBC__) && defined(__GLIBC_MINOR__) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)) - x = strtod_l(buf, &endptr, loc); - freelocale(loc); -#else - if (*dec == '.') { - x = strtod(buf, &endptr); - } - else if (NULL == strchr(buf, '.')) { - x = strtod(buf, &endptr); - } - else { - char* p = strchr(buf, '.'); - *p = *dec; - x = strtod(buf, &endptr); - } -#endif - if (*endptr == 0) { - *number = x; - *nextIndex = token_start + total_length; - return; - } - } - - /* Token missing or cannot be converted to result type. */ - -Modelica_ERROR: - *nextIndex = startIndex; - *number = 0; - return; -} - -void ModelicaStrings_scanString(_In_z_ const char* string, int startIndex, - _Out_ int* nextIndex, _Out_ const char** result) { - int i, token_start, past_token, token_length; - - token_start = ModelicaStrings_skipWhiteSpace(string, startIndex); - i = token_start; - if (string[token_start-1] != '"') { - goto Modelica_ERROR; - } - /* Index of first char of token, after ws. */ - - ++i; - while (1) { - if (string[i-1] == '\0') { - goto Modelica_ERROR; - } - if (string[i-2] == '\\' && string[i-1] == '"') - ; /* escaped quote, consume */ - else if (string[i-1] == '"') { - break; /* end quote */ - } - ++i; - } - past_token = i + 1; - /* Index of first char after token, ws or separator. */ - - token_length = past_token-token_start-2; - - if (token_length > 0) { - char* s = ModelicaAllocateString((size_t)token_length); - strncpy(s, string+token_start, (size_t)token_length); - s[token_length] = '\0'; - *result = s; - *nextIndex = past_token; - return; - } - -Modelica_ERROR: - { - char* s = ModelicaAllocateString(0); - s[0] = '\0'; - *result = s; - } - *nextIndex = startIndex; - return; -} - -/* AP hash function macro variant of the one listed at - http://www.partow.net/programming/hashfunctions/index.html#APHashFunction - - Copyright (C) 2002, Arash Partow - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ -#define HASH_AP(key, keylen, hash) \ -do { \ - unsigned _hb_keylen = (unsigned)keylen; \ - const unsigned char *_hb_key = (const unsigned char*)(key); \ - unsigned int i; \ - hash = 0xAAAAAAAA; \ - for (i = 0; i < _hb_keylen; _hb_key++, i++) { \ - hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ (*_hb_key) * (hash >> 3)) : \ - (~((hash << 11) + ((*_hb_key) ^ (hash >> 5)))); \ - } \ -} while (0) - -#undef HASH_FUNCTION -#define HASH_FUNCTION HASH_AP - -int ModelicaStrings_hashString(_In_z_ const char* str) { - /* Compute an unsigned int hash code from a character string */ - size_t len = strlen(str); - union hash_tag { - unsigned int iu; - int is; - } h; - - HASH_VALUE(str, len, h.iu); - - return h.is; -} - -#undef HASH_FUNCTION -#define HASH_FUNCTION HASH_JEN - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif diff --git a/ModelicaExternalC/C-Sources/ModelicaStrings.h b/ModelicaExternalC/C-Sources/ModelicaStrings.h deleted file mode 100644 index 0b274720b..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaStrings.h +++ /dev/null @@ -1,104 +0,0 @@ -/* ModelicaStrings.h - External functions header for Modelica.Utilities.Strings - - Copyright (C) 2002-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* The functions are mostly non-portable. The following #define's are used - to define the system calls of the operating system - - NO_LOCALE : locale.h is not present (e.g. on AVR). - MODELICA_EXPORT: Prefix used for function calls. If not defined, blank is used - Useful definition: - - "__declspec(dllexport)" if included in a DLL and the - functions shall be visible outside of the DLL -*/ - -#ifndef MODELICA_STRINGS_H_ -#define MODELICA_STRINGS_H_ - -#include - -#if !defined(MODELICA_EXPORT) -#if defined(__cplusplus) -#define MODELICA_EXPORT extern "C" -#else -#define MODELICA_EXPORT -#endif -#endif - -/* - * Non-null pointers and esp. null-terminated strings need to be passed to - * external functions. - * - * The following macros handle nonnull attributes for GNU C and Microsoft SAL. - */ -#undef MODELICA_NONNULLATTR -#undef MODELICA_RETURNNONNULLATTR -#if defined(__GNUC__) -#define MODELICA_NONNULLATTR __attribute__((nonnull)) -#if defined(__GNUC_MINOR__) && (__GNUC__ > 3 && __GNUC_MINOR__ > 8) -#define MODELICA_RETURNNONNULLATTR __attribute__((returns_nonnull)) -#else -#define MODELICA_RETURNNONNULLATTR -#endif -#elif defined(__ATTR_SAL) -#define MODELICA_NONNULLATTR -#define MODELICA_RETURNNONNULLATTR _Ret_z_ /* _Ret_notnull_ and null-terminated */ -#else -#define MODELICA_NONNULLATTR -#define MODELICA_RETURNNONNULLATTR -#endif -#if !defined(__ATTR_SAL) -#undef _In_z_ -#undef _Out_ -#undef _Ret_z_ -#define _In_z_ -#define _Out_ -#define _Ret_z_ -#endif - -MODELICA_EXPORT MODELICA_RETURNNONNULLATTR const char* ModelicaStrings_substring( - _In_z_ const char* string, int startIndex, int endIndex) MODELICA_NONNULLATTR; -MODELICA_EXPORT int ModelicaStrings_length(_In_z_ const char* string) MODELICA_NONNULLATTR; -MODELICA_EXPORT int ModelicaStrings_compare(_In_z_ const char* string1, - _In_z_ const char* string2, int caseSensitive) MODELICA_NONNULLATTR; -MODELICA_EXPORT int ModelicaStrings_skipWhiteSpace(_In_z_ const char* string, - int i) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaStrings_scanIdentifier(_In_z_ const char* string, - int startIndex, _Out_ int* nextIndex, _Out_ const char** identifier) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaStrings_scanInteger(_In_z_ const char* string, - int startIndex, int unsignedNumber, _Out_ int* nextIndex, - _Out_ int* integerNumber) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaStrings_scanReal(_In_z_ const char* string, int startIndex, - int unsignedNumber, _Out_ int* nextIndex, _Out_ double* number) MODELICA_NONNULLATTR; -MODELICA_EXPORT void ModelicaStrings_scanString(_In_z_ const char* string, int startIndex, - _Out_ int* nextIndex, _Out_ const char** result) MODELICA_NONNULLATTR; -MODELICA_EXPORT int ModelicaStrings_hashString(_In_z_ const char* str) MODELICA_NONNULLATTR; - -#endif diff --git a/ModelicaExternalC/C-Sources/ModelicaUtilities.h b/ModelicaExternalC/C-Sources/ModelicaUtilities.h deleted file mode 100644 index be3e941e5..000000000 --- a/ModelicaExternalC/C-Sources/ModelicaUtilities.h +++ /dev/null @@ -1,208 +0,0 @@ -/* ModelicaUtilities.h - External utility functions header - - Copyright (C) 2010-2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* Utility functions which can be called by external Modelica functions. - - These functions are defined in section 12.8.6 of the - Modelica Specification 3.0 and section 12.9.6 of the - Modelica Specification 3.1 and later. - - A generic C-implementation of these functions cannot be given, - because it is tool dependent how strings are output in a - window of the respective simulation tool. Therefore, only - this header file is shipped with the Modelica Standard Library. -*/ - -#ifndef MODELICA_UTILITIES_H -#define MODELICA_UTILITIES_H - -#include -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - Some of the functions never return to the caller. In order to compile - external Modelica C-code in most compilers, noreturn attributes need to - be present to avoid warnings or errors. - - The following macros handle noreturn attributes according to the - C11/C++11 standard with fallback to GNU, Clang or MSVC extensions if using - an older compiler. -*/ -#undef MODELICA_NORETURN -#undef MODELICA_NORETURNATTR -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -#define MODELICA_NORETURN _Noreturn -#define MODELICA_NORETURNATTR -#elif defined(__cplusplus) && __cplusplus >= 201103L -#if (defined(__GNUC__) && __GNUC__ >= 5) || \ - (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 8) -#define MODELICA_NORETURN [[noreturn]] -#define MODELICA_NORETURNATTR -#elif (defined(__GNUC__) && __GNUC__ >= 3) || \ - (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 2 && __GNUC_MINOR__ >= 8) -#define MODELICA_NORETURN -#define MODELICA_NORETURNATTR __attribute__((noreturn)) -#elif defined(__GNUC__) -#define MODELICA_NORETURN -#define MODELICA_NORETURNATTR -#else -#define MODELICA_NORETURN [[noreturn]] -#define MODELICA_NORETURNATTR -#endif -#elif defined(__clang__) -/* Encapsulated for Clang since GCC fails to process __has_attribute */ -#if __has_attribute(noreturn) -#define MODELICA_NORETURN -#define MODELICA_NORETURNATTR __attribute__((noreturn)) -#else -#define MODELICA_NORETURN -#define MODELICA_NORETURNATTR -#endif -#elif (defined(__GNUC__) && __GNUC__ >= 3) || \ - (defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 2 && __GNUC_MINOR__ >= 8) || \ - (defined(__SUNPRO_C) && __SUNPRO_C >= 0x5110) -#define MODELICA_NORETURN -#define MODELICA_NORETURNATTR __attribute__((noreturn)) -#elif (defined(_MSC_VER) && _MSC_VER >= 1200) || \ - defined(__BORLANDC__) -#define MODELICA_NORETURN __declspec(noreturn) -#define MODELICA_NORETURNATTR -#else -#define MODELICA_NORETURN -#define MODELICA_NORETURNATTR -#endif - -/* - The following macros handle format attributes for type-checks against a - format string. -*/ - -#if defined(__clang__) -/* Encapsulated for Clang since GCC fails to process __has_attribute */ -#if __has_attribute(format) -#define MODELICA_FORMATATTR_PRINTF __attribute__((format(printf, 1, 2))) -#define MODELICA_FORMATATTR_VPRINTF __attribute__((format(printf, 1, 0))) -#else -#define MODELICA_FORMATATTR_PRINTF -#define MODELICA_FORMATATTR_VPRINTF -#endif -#elif defined(__GNUC__) && __GNUC__ >= 3 -#define MODELICA_FORMATATTR_PRINTF __attribute__((format(printf, 1, 2))) -#define MODELICA_FORMATATTR_VPRINTF __attribute__((format(printf, 1, 0))) -#else -#define MODELICA_FORMATATTR_PRINTF -#define MODELICA_FORMATATTR_VPRINTF -#endif - -void ModelicaMessage(const char *string); -/* -Output the message string (no format control). -*/ - - -void ModelicaFormatMessage(const char *string, ...) MODELICA_FORMATATTR_PRINTF; -/* -Output the message under the same format control as the C-function printf. -*/ - - -void ModelicaVFormatMessage(const char *string, va_list args) MODELICA_FORMATATTR_VPRINTF; -/* -Output the message under the same format control as the C-function vprintf. -*/ - - -MODELICA_NORETURN void ModelicaError(const char *string) MODELICA_NORETURNATTR; -/* -Output the error message string (no format control). This function -never returns to the calling function, but handles the error -similarly to an assert in the Modelica code. -*/ - -void ModelicaWarning(const char *string); -/* -Output the warning message string (no format control). -*/ - -void ModelicaFormatWarning(const char *string, ...) MODELICA_FORMATATTR_PRINTF; -/* -Output the warning message under the same format control as the C-function printf. -*/ - -void ModelicaVFormatWarning(const char *string, va_list args) MODELICA_FORMATATTR_VPRINTF; -/* -Output the warning message under the same format control as the C-function vprintf. -*/ - -MODELICA_NORETURN void ModelicaFormatError(const char *string, ...) MODELICA_NORETURNATTR MODELICA_FORMATATTR_PRINTF; -/* -Output the error message under the same format control as the C-function -printf. This function never returns to the calling function, -but handles the error similarly to an assert in the Modelica code. -*/ - - -MODELICA_NORETURN void ModelicaVFormatError(const char *string, va_list args) MODELICA_NORETURNATTR MODELICA_FORMATATTR_VPRINTF; -/* -Output the error message under the same format control as the C-function -vprintf. This function never returns to the calling function, -but handles the error similarly to an assert in the Modelica code. -*/ - - -char* ModelicaAllocateString(size_t len); -/* -Allocate memory for a Modelica string which is used as return -argument of an external Modelica function. Note, that the storage -for string arrays (= pointer to string array) is still provided by the -calling program, as for any other array. If an error occurs, this -function does not return, but calls "ModelicaError". -*/ - - -char* ModelicaAllocateStringWithErrorReturn(size_t len); -/* -Same as ModelicaAllocateString, except that in case of error, the -function returns 0. This allows the external function to close files -and free other open resources in case of error. After cleaning up -resources use ModelicaError or ModelicaFormatError to signal -the error. -*/ - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/ModelicaExternalC/C-Sources/gconstructor.h b/ModelicaExternalC/C-Sources/gconstructor.h deleted file mode 100644 index a71123233..000000000 --- a/ModelicaExternalC/C-Sources/gconstructor.h +++ /dev/null @@ -1,124 +0,0 @@ -/* gconstructor.h - Module constructor and destructor helper header - - If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and - destructors, in a sane way, including e.g. on library unload. If not you're on - your own. - - Some compilers need #pragma to handle this, which does not work with macros, - so the way you need to use this is (for constructors): - - #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA - #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor) - #endif - G_DEFINE_CONSTRUCTOR(my_constructor) - static void my_constructor(void) { - ... - } - -*/ - -#ifndef G_CONSTRUCTOR_H_ -#define G_CONSTRUCTOR_H_ - -#if defined(__cplusplus) - -#define G_HAS_CONSTRUCTORS 1 - -#define G_DEFINE_CONSTRUCTOR(_func) \ - static void _func(void); \ - struct _func ## _wrapper_struct { _func ## _wrapper_struct() { _func(); } }; \ - static _func ## _wrapper_struct _func ## _wrapper; - -#define G_DEFINE_DESTRUCTOR(_func) \ - static void _func(void); \ - struct _func ## _wrapper_struct2 { ~_func ## _wrapper_struct2() { _func(); } }; \ - static _func ## _wrapper_struct2 _func ## _wrapper2; - -#elif (defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))) || \ - defined(__clang__) - -#define G_HAS_CONSTRUCTORS 1 - -#define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void); -#define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void); - -#elif defined(_MSC_VER) && (_MSC_VER >= 1500) -/* Visual Studio 2008 and later has _pragma */ - -#define G_HAS_CONSTRUCTORS 1 - -#ifdef _WIN64 -#define G_MSVC_SYMBOL_PREFIX "" -#else -#define G_MSVC_SYMBOL_PREFIX "_" -#endif - -#define G_DEFINE_CONSTRUCTOR(_func) G_MSVC_CTOR (_func, G_MSVC_SYMBOL_PREFIX) -#define G_DEFINE_DESTRUCTOR(_func) G_MSVC_DTOR (_func, G_MSVC_SYMBOL_PREFIX) - -#define G_MSVC_CTOR(_func,_sym_prefix) \ - static void _func(void); \ - extern int (* _array ## _func)(void); \ - int _func ## _wrapper(void) { _func(); return _array ## _func == NULL; } \ - __pragma(comment(linker,"/include:" _sym_prefix # _func "_wrapper")) \ - __pragma(section(".CRT$XCU",read)) \ - __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _wrapper; - -#define G_MSVC_DTOR(_func,_sym_prefix) \ - static void _func(void); \ - extern int (* _array ## _func)(void); \ - int _func ## _constructor(void) { atexit (_func); return _array ## _func == NULL; } \ - __pragma(comment(linker,"/include:" _sym_prefix # _func "_constructor")) \ - __pragma(section(".CRT$XCU",read)) \ - __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _constructor; - -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) - -#define G_HAS_CONSTRUCTORS 1 - -/* Pre Visual Studio 2008 must use #pragma section */ -#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 -#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 - -#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ - section(".CRT$XCU",read) -#define G_DEFINE_CONSTRUCTOR(_func) \ - static void _func(void); \ - static int _func ## _wrapper(void) { _func(); return 0; } \ - __declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper; - -#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ - section(".CRT$XCU",read) -#define G_DEFINE_DESTRUCTOR(_func) \ - static void _func(void); \ - static int _func ## _constructor(void) { atexit (_func); return 0; } \ - __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor; - -#elif defined(__SUNPRO_C) - -/* This is not tested, but I believe it should work, based on: - * http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c - */ - -#define G_HAS_CONSTRUCTORS 1 - -#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 -#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 - -#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ - init(_func) -#define G_DEFINE_CONSTRUCTOR(_func) \ - static void _func(void); - -#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ - fini(_func) -#define G_DEFINE_DESTRUCTOR(_func) \ - static void _func(void); - -#else - -/* constructors not supported for this compiler */ - -#endif - -#endif diff --git a/ModelicaExternalC/C-Sources/read_data_impl.h b/ModelicaExternalC/C-Sources/read_data_impl.h deleted file mode 100644 index 6de4cdf7e..000000000 --- a/ModelicaExternalC/C-Sources/read_data_impl.h +++ /dev/null @@ -1,596 +0,0 @@ -/* - * Copyright (c) 2019-2020, Christopher C. Hulbert - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#define READ_TYPE_DOUBLE_DATA CAT(READ_TYPED_FUNC1, Double) -#define READ_TYPE_SINGLE_DATA CAT(READ_TYPED_FUNC1, Single) -#define READ_TYPE_INT32_DATA CAT(READ_TYPED_FUNC1, Int32) -#define READ_TYPE_UINT32_DATA CAT(READ_TYPED_FUNC1, UInt32) -#define READ_TYPE_INT16_DATA CAT(READ_TYPED_FUNC1, Int16) -#define READ_TYPE_UINT16_DATA CAT(READ_TYPED_FUNC1, UInt16) -#define READ_TYPE_INT8_DATA CAT(READ_TYPED_FUNC1, Int8) -#define READ_TYPE_UINT8_DATA CAT(READ_TYPED_FUNC1, UInt8) -#ifdef HAVE_MATIO_INT64_T -#define READ_TYPE_INT64_DATA CAT(READ_TYPED_FUNC1, Int64) -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T -#define READ_TYPE_UINT64_DATA CAT(READ_TYPED_FUNC1, UInt64) -#endif /* HAVE_MATIO_UINT64_T */ - -static size_t -READ_TYPE_DOUBLE_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_DOUBLE - readcount = fread(data, sizeof(double), len, (FILE*)mat->fp); - if ( readcount == len && mat->byteswap ) { - size_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_doubleSwap(data + i); - } - } -#else - size_t i; - const size_t data_size = sizeof(double); - double v[READ_BLOCK_SIZE/sizeof(double)]; - READ_DATA(READ_TYPE, Mat_doubleSwap); -#endif - return readcount; -} - -static size_t -READ_TYPE_SINGLE_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_SINGLE - readcount = fread(data, sizeof(float), len, (FILE*)mat->fp); - if ( readcount == len && mat->byteswap ) { - size_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_floatSwap(data + i); - } - } -#else - size_t i; - const size_t data_size = sizeof(float); - float v[READ_BLOCK_SIZE/sizeof(float)]; - READ_DATA(READ_TYPE, Mat_floatSwap); -#endif - return readcount; -} - -static size_t -READ_TYPE_INT32_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_INT32 - readcount = fread(data, sizeof(mat_int32_t), len, (FILE*)mat->fp); - if ( readcount == len && mat->byteswap ) { - size_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_int32Swap(data + i); - } - } -#else - size_t i; - const size_t data_size = sizeof(mat_int32_t); - mat_int32_t v[READ_BLOCK_SIZE/sizeof(mat_int32_t)]; - READ_DATA(READ_TYPE, Mat_int32Swap); -#endif - return readcount; -} - -static size_t -READ_TYPE_UINT32_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_UINT32 - readcount = fread(data, sizeof(mat_uint32_t), len, (FILE*)mat->fp); - if ( readcount == len && mat->byteswap ) { - size_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_uint32Swap(data + i); - } - } -#else - size_t i; - const size_t data_size = sizeof(mat_uint32_t); - mat_uint32_t v[READ_BLOCK_SIZE/sizeof(mat_uint32_t)]; - READ_DATA(READ_TYPE, Mat_uint32Swap); -#endif - return readcount; -} - -static size_t -READ_TYPE_INT16_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_INT16 - readcount = fread(data, sizeof(mat_int16_t), len, (FILE*)mat->fp); - if ( readcount == len && mat->byteswap ) { - size_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_int16Swap(data + i); - } - } -#else - size_t i; - const size_t data_size = sizeof(mat_int16_t); - mat_int16_t v[READ_BLOCK_SIZE/sizeof(mat_int16_t)]; - READ_DATA(READ_TYPE, Mat_int16Swap); -#endif - return readcount; -} - -static size_t -READ_TYPE_UINT16_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_UINT16 - readcount = fread(data, sizeof(mat_uint16_t), len, (FILE*)mat->fp); - if ( readcount == len && mat->byteswap ) { - size_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_uint16Swap(data + i); - } - } -#else - size_t i; - const size_t data_size = sizeof(mat_uint16_t); - mat_uint16_t v[READ_BLOCK_SIZE/sizeof(mat_uint16_t)]; - READ_DATA(READ_TYPE, Mat_uint16Swap); -#endif - return readcount; -} - -static size_t -READ_TYPE_INT8_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_INT8 - readcount = fread(data, sizeof(mat_int8_t), len, (FILE*)mat->fp); -#else - size_t i; - const size_t data_size = sizeof(mat_int8_t); - mat_int8_t v[READ_BLOCK_SIZE/sizeof(mat_int8_t)]; - READ_DATA_NOSWAP(READ_TYPE); -#endif - return readcount; -} - -static size_t -READ_TYPE_UINT8_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_UINT8 - readcount = fread(data, sizeof(mat_uint8_t), len, (FILE*)mat->fp); -#else - size_t i; - const size_t data_size = sizeof(mat_uint8_t); - mat_uint8_t v[READ_BLOCK_SIZE/sizeof(mat_uint8_t)]; - READ_DATA_NOSWAP(READ_TYPE); -#endif - return readcount; -} - -#ifdef HAVE_MATIO_INT64_T -static size_t -READ_TYPE_INT64_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_INT64 - readcount = fread(data, sizeof(mat_int64_t), len, (FILE*)mat->fp); - if ( readcount == len && mat->byteswap ) { - size_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_int64Swap(data + i); - } - } -#else - size_t i; - const size_t data_size = sizeof(mat_int64_t); - mat_int64_t v[READ_BLOCK_SIZE/sizeof(mat_int64_t)]; - READ_DATA(READ_TYPE, Mat_int64Swap); -#endif - return readcount; -} -#endif /* HAVE_MATIO_INT64_T */ - -#ifdef HAVE_MATIO_UINT64_T -static size_t -READ_TYPE_UINT64_DATA(mat_t *mat, READ_TYPE *data, size_t len) -{ - size_t readcount; -#if READ_TYPE_TYPE == READ_TYPE_UINT64 - readcount = fread(data, sizeof(mat_uint64_t), len, (FILE*)mat->fp); - if ( readcount == len && mat->byteswap ) { - size_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_uint64Swap(data + i); - } - } -#else - size_t i; - const size_t data_size = sizeof(mat_uint64_t); - mat_uint64_t v[READ_BLOCK_SIZE/sizeof(mat_uint64_t)]; - READ_DATA(READ_TYPE, Mat_uint64Swap); -#endif - return readcount; -} -#endif /* HAVE_MATIO_UINT64_T */ - - -/** @brief Reads data of type @c data_type into a READ_TYPE type - * - * Reads from the MAT file @c len elements of data type @c data_type storing - * them as READ_TYPE's in @c data. - * @ingroup mat_internal - * @param mat MAT file pointer - * @param data Pointer to store the output values (len*sizeof(READ_TYPE)) - * @param data_type one of the @c matio_types enumerations which is the source - * data type in the file - * @param len Number of elements of type @c data_type to read from the file - * @retval Number of elements read from the file - */ -static size_t -READ_TYPED_FUNC1(mat_t *mat, READ_TYPE *data, enum matio_types data_type, size_t len) -{ - size_t readcount; - - if ( mat == NULL || data == NULL || mat->fp == NULL ) - return 0; - - switch ( data_type ) { - case MAT_T_DOUBLE: - readcount = READ_TYPE_DOUBLE_DATA(mat, data, len); - break; - case MAT_T_SINGLE: - readcount = READ_TYPE_SINGLE_DATA(mat, data, len); - break; -#ifdef HAVE_MATIO_INT64_T - case MAT_T_INT64: - readcount = READ_TYPE_INT64_DATA(mat, data, len); - break; -#endif /* HAVE_MATIO_UINT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_T_UINT64: - readcount = READ_TYPE_UINT64_DATA(mat, data, len); - break; -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_T_INT32: - readcount = READ_TYPE_INT32_DATA(mat, data, len); - break; - case MAT_T_UINT32: - readcount = READ_TYPE_UINT32_DATA(mat, data, len); - break; - case MAT_T_INT16: - readcount = READ_TYPE_INT16_DATA(mat, data, len); - break; - case MAT_T_UINT16: - readcount = READ_TYPE_UINT16_DATA(mat, data, len); - break; - case MAT_T_INT8: - readcount = READ_TYPE_INT8_DATA(mat, data, len); - break; - case MAT_T_UINT8: - readcount = READ_TYPE_UINT8_DATA(mat, data, len); - break; - default: - readcount = 0; - break; - } - return readcount; -} - -#undef READ_TYPE_DOUBLE_DATA -#undef READ_TYPE_SINGLE_DATA -#undef READ_TYPE_INT32_DATA -#undef READ_TYPE_UINT32_DATA -#undef READ_TYPE_INT16_DATA -#undef READ_TYPE_UINT16_DATA -#undef READ_TYPE_INT8_DATA -#undef READ_TYPE_UINT8_DATA -#ifdef HAVE_MATIO_INT64_T -#undef READ_TYPE_INT64_DATA -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T -#undef READ_TYPE_UINT64_DATA -#endif /* HAVE_MATIO_UINT64_T */ - -#if HAVE_ZLIB - -#define READ_TYPE_DOUBLE_DATA CAT(READ_TYPED_FUNC2, Double) -#define READ_TYPE_SINGLE_DATA CAT(READ_TYPED_FUNC2, Single) -#define READ_TYPE_INT32_DATA CAT(READ_TYPED_FUNC2, Int32) -#define READ_TYPE_UINT32_DATA CAT(READ_TYPED_FUNC2, UInt32) -#define READ_TYPE_INT16_DATA CAT(READ_TYPED_FUNC2, Int16) -#define READ_TYPE_UINT16_DATA CAT(READ_TYPED_FUNC2, UInt16) -#define READ_TYPE_INT8_DATA CAT(READ_TYPED_FUNC2, Int8) -#define READ_TYPE_UINT8_DATA CAT(READ_TYPED_FUNC2, UInt8) -#ifdef HAVE_MATIO_INT64_T -#define READ_TYPE_INT64_DATA CAT(READ_TYPED_FUNC2, Int64) -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T -#define READ_TYPE_UINT64_DATA CAT(READ_TYPED_FUNC2, UInt64) -#endif /* HAVE_MATIO_UINT64_T */ - -static void -READ_TYPE_DOUBLE_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_DOUBLE - InflateData(mat, z, data, len*sizeof(double)); - if ( mat->byteswap ) { - mat_uint32_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_doubleSwap(data + i); - } - } -#else - mat_uint32_t i; - const size_t data_size = sizeof(double); - double v[READ_BLOCK_SIZE/sizeof(double)]; - READ_COMPRESSED_DATA(READ_TYPE, Mat_doubleSwap); -#endif -} - -static void -READ_TYPE_SINGLE_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_SINGLE - InflateData(mat, z, data, len*sizeof(float)); - if ( mat->byteswap ) { - mat_uint32_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_floatSwap(data + i); - } - } -#else - mat_uint32_t i; - const size_t data_size = sizeof(float); - float v[READ_BLOCK_SIZE/sizeof(float)]; - READ_COMPRESSED_DATA(READ_TYPE, Mat_floatSwap); -#endif -} - -#ifdef HAVE_MATIO_INT64_T -static void -READ_TYPE_INT64_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_INT64 - InflateData(mat, z, data, len*sizeof(mat_int64_t)); - if ( mat->byteswap ) { - mat_uint32_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_int64Swap(data + i); - } - } -#else - mat_uint32_t i; - const size_t data_size = sizeof(mat_int64_t); - mat_int64_t v[READ_BLOCK_SIZE/sizeof(mat_int64_t)]; - READ_COMPRESSED_DATA(READ_TYPE, Mat_int64Swap); -#endif -} -#endif /* HAVE_MATIO_INT64_T */ - -#ifdef HAVE_MATIO_UINT64_T -static void -READ_TYPE_UINT64_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_UINT64 - InflateData(mat, z, data, len*sizeof(mat_uint64_t)); - if ( mat->byteswap ) { - mat_uint32_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_uint64Swap(data + i); - } - } -#else - mat_uint32_t i; - const size_t data_size = sizeof(mat_uint64_t); - mat_uint64_t v[READ_BLOCK_SIZE/sizeof(mat_uint64_t)]; - READ_COMPRESSED_DATA(READ_TYPE, Mat_uint64Swap); -#endif -} -#endif /* HAVE_MATIO_UINT64_T */ - -static void -READ_TYPE_INT32_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_INT32 - InflateData(mat, z, data, len*sizeof(mat_int32_t)); - if ( mat->byteswap ) { - mat_uint32_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_int32Swap(data + i); - } - } -#else - mat_uint32_t i; - const size_t data_size = sizeof(mat_int32_t); - mat_int32_t v[READ_BLOCK_SIZE/sizeof(mat_int32_t)]; - READ_COMPRESSED_DATA(READ_TYPE, Mat_int32Swap); -#endif -} - -static void -READ_TYPE_UINT32_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_UINT32 - InflateData(mat, z, data, len*sizeof(mat_uint32_t)); - if ( mat->byteswap ) { - mat_uint32_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_uint32Swap(data + i); - } - } -#else - mat_uint32_t i; - const size_t data_size = sizeof(mat_uint32_t); - mat_uint32_t v[READ_BLOCK_SIZE/sizeof(mat_uint32_t)]; - READ_COMPRESSED_DATA(READ_TYPE, Mat_uint32Swap); -#endif -} - -static void -READ_TYPE_INT16_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_INT16 - InflateData(mat, z, data, len*sizeof(mat_int16_t)); - if ( mat->byteswap ) { - mat_uint32_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_int16Swap(data + i); - } - } -#else - mat_uint32_t i; - const size_t data_size = sizeof(mat_int16_t); - mat_int16_t v[READ_BLOCK_SIZE/sizeof(mat_int16_t)]; - READ_COMPRESSED_DATA(READ_TYPE, Mat_int16Swap); -#endif -} - -static void -READ_TYPE_UINT16_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_UINT16 - InflateData(mat, z, data, len*sizeof(mat_uint16_t)); - if ( mat->byteswap ) { - mat_uint32_t i; - for ( i = 0; i < len; i++ ) { - (void)Mat_uint16Swap(data + i); - } - } -#else - mat_uint32_t i; - const size_t data_size = sizeof(mat_uint16_t); - mat_uint16_t v[READ_BLOCK_SIZE/sizeof(mat_uint16_t)]; - READ_COMPRESSED_DATA(READ_TYPE, Mat_uint16Swap); -#endif -} - -static void -READ_TYPE_INT8_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_INT8 - InflateData(mat, z, data, len*sizeof(mat_int8_t)); -#else - mat_uint32_t i; - const size_t data_size = sizeof(mat_int8_t); - mat_int8_t v[READ_BLOCK_SIZE/sizeof(mat_int8_t)]; - READ_COMPRESSED_DATA_NOSWAP(READ_TYPE); -#endif -} - -static void -READ_TYPE_UINT8_DATA(mat_t *mat, z_streamp z, READ_TYPE *data, mat_uint32_t len) -{ -#if READ_TYPE_TYPE == READ_TYPE_UINT8 - InflateData(mat, z, data, len*sizeof(mat_uint8_t)); -#else - mat_uint32_t i; - const size_t data_size = sizeof(mat_uint8_t); - mat_uint8_t v[READ_BLOCK_SIZE/sizeof(mat_uint8_t)]; - READ_COMPRESSED_DATA_NOSWAP(READ_TYPE); -#endif -} - -/** @brief Reads data of type @c data_type into a READ_TYPE type - * - * Reads from the MAT file @c len compressed elements of data type @c data_type - * storing them as READ_TYPE's in @c data. - * @ingroup mat_internal - * @param mat MAT file pointer - * @param z Pointer to the zlib stream for inflation - * @param data Pointer to store the output values (len*sizeof(READ_TYPE)) - * @param data_type one of the @c matio_types enumerations which is the source - * data type in the file - * @param len Number of elements of type @c data_type to read from the file - * @retval Number of bytes read from the file - */ -static int -READ_TYPED_FUNC2(mat_t *mat, z_streamp z, READ_TYPE *data, enum matio_types data_type, int len) -{ - if ( mat == NULL || data == NULL || mat->fp == NULL ) - return 0; - - switch ( data_type ) { - case MAT_T_DOUBLE: - READ_TYPE_DOUBLE_DATA(mat, z, data, len); - break; - case MAT_T_SINGLE: - READ_TYPE_SINGLE_DATA(mat, z, data, len); - break; -#ifdef HAVE_MATIO_INT64_T - case MAT_T_INT64: - READ_TYPE_INT64_DATA(mat, z, data, len); - break; -#endif /* HAVE_MATIO_UINT64_T */ -#ifdef HAVE_MATIO_UINT64_T - case MAT_T_UINT64: - READ_TYPE_UINT64_DATA(mat, z, data, len); - break; -#endif /* HAVE_MATIO_UINT64_T */ - case MAT_T_INT32: - READ_TYPE_INT32_DATA(mat, z, data, len); - break; - case MAT_T_UINT32: - READ_TYPE_UINT32_DATA(mat, z, data, len); - break; - case MAT_T_INT16: - READ_TYPE_INT16_DATA(mat, z, data, len); - break; - case MAT_T_UINT16: - READ_TYPE_UINT16_DATA(mat, z, data, len); - break; - case MAT_T_INT8: - READ_TYPE_INT8_DATA(mat, z, data, len); - break; - case MAT_T_UINT8: - READ_TYPE_UINT8_DATA(mat, z, data, len); - break; - default: - break; - } - return len*Mat_SizeOf(data_type); -} - -#undef READ_TYPE_DOUBLE_DATA -#undef READ_TYPE_SINGLE_DATA -#undef READ_TYPE_INT32_DATA -#undef READ_TYPE_UINT32_DATA -#undef READ_TYPE_INT16_DATA -#undef READ_TYPE_UINT16_DATA -#undef READ_TYPE_INT8_DATA -#undef READ_TYPE_UINT8_DATA -#ifdef HAVE_MATIO_INT64_T -#undef READ_TYPE_INT64_DATA -#endif /* HAVE_MATIO_INT64_T */ -#ifdef HAVE_MATIO_UINT64_T -#undef READ_TYPE_UINT64_DATA -#endif /* HAVE_MATIO_UINT64_T */ - -#endif diff --git a/ModelicaExternalC/C-Sources/readme.txt b/ModelicaExternalC/C-Sources/readme.txt deleted file mode 100644 index 8103e4671..000000000 --- a/ModelicaExternalC/C-Sources/readme.txt +++ /dev/null @@ -1,56 +0,0 @@ -All *.c files in this directory should be compiled by a tool vendor -to the following object libraries - -- ModelicaExternalC (.lib, .dll, .a, .so, depending on tool and OS) containing: - ModelicaFFT.c - ModelicaInternal.c - ModelicaRandom.c - ModelicaStrings.c - win32_dirent.c (for Visual C++ on Windows) - -- ModelicaIO (.lib, .dll, .a, .so, depending on tool and OS) containing: - ModelicaIO.c - -- ModelicaMatIO (.lib, .dll, .a, .so, depending on tool and OS) containing: - ModelicaMatIO.c - snprintf.c - -- ModelicaStandardTables (.lib, .dll, .a, .so, depending on tool and OS) containing: - ModelicaStandardTables.c - ModelicaStandardTablesUsertab.c - -- zlib (.lib, .dll, .a, .so, depending on tool and OS) containing: - zlib/*.c - -When the library annotation "ModelicaExternalC", "ModelicaIO" or -"ModelicaStandardTables" is utilized in an external Modelica function, then the -respective object library should be provided by the linker or should be -dynamically linked to the simulation environment. - -For backwards-compatibility with the Modelica Standard Library (MSL) v3.2.1, a -tool vendor supporting MSL v3.2.1 and later releases has to provide the library -"ModelicaStandardTables" in such a way that the required library dependencies -(i.e., libraries "ModelicaIO", "ModelicaMatIO" and "zlib") are automatically -resolved. For instance, this can be achieved by building shared object -libraries (.dll, .so) and dynamically linking library "ModelicaStandardTables" to -"ModelicaIO", "ModelicaIO" to "ModelicaMatIO" and "ModelicaMatIO" to "zlib". - -On Windows, when compiling libraries (.dll, .lib) or executables (.exe) with -C sources including gconstructor.h, particularly, projects that build -ModelicaInternal.c or ModelicaStandardTables.c, the following (optimization) -options shall be applied in the Release configuration of Visual Studio 2013, 2015 -or 2017: -- Compiler: /Zc:inline (Remove unreferenced COMDAT) must not be set. Either do not - set this option at all or explicitly set /Zc:inline- to unset -- Linker: /OPT:NOREF (Keep unreferenced functions) should be set, in case - /GL (Whole Program Optimization) and /LTCG (Link-time Code Generation) are set - -Build projects for the object libraries are provided under - ../BuildProjects - -Additionally, a tool vendor has to provide library "lapack" -(>= v3.1; download from http://www.netlib.org/lapack) -and this library should be used in the linker when a model is compiled -that uses this library in its library annotation. - -January 05, 2018. diff --git a/ModelicaExternalC/C-Sources/safe-math.h b/ModelicaExternalC/C-Sources/safe-math.h deleted file mode 100644 index 7fa270e55..000000000 --- a/ModelicaExternalC/C-Sources/safe-math.h +++ /dev/null @@ -1,1078 +0,0 @@ -/* Overflow-safe math functions - * Portable Snippets - https://github.com/nemequ/portable-snippets - * Created by Evan Nemerson - * - * To the extent possible under law, the authors have waived all - * copyright and related or neighboring rights to this code. For - * details, see the Creative Commons Zero 1.0 Universal license at - * https://creativecommons.org/publicdomain/zero/1.0/ - */ - -#if !defined(PSNIP_SAFE_H) -#define PSNIP_SAFE_H - -#if !defined(PSNIP_SAFE_FORCE_PORTABLE) -# if defined(__has_builtin) -# if __has_builtin(__builtin_add_overflow) && !defined(__ibmxl__) -# define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW -# endif -# elif defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__INTEL_COMPILER) -# define PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW -# endif -# if defined(HAVE_INTSAFE_H) -# define PSNIP_SAFE_HAVE_INTSAFE_H -# elif defined(__has_include) -# if __has_include() -# define PSNIP_SAFE_HAVE_INTSAFE_H -# endif -# elif defined(_MSC_VER) && _MSC_VER >= 1600 -# define PSNIP_SAFE_HAVE_INTSAFE_H -# elif defined(__CYGWIN__) && defined(__GNUC__) && __GNUC__ >= 5 -# define PSNIP_SAFE_HAVE_INTSAFE_H -# endif -#endif /* !defined(PSNIP_SAFE_FORCE_PORTABLE) */ - -#if defined(__GNUC__) -# define PSNIP_SAFE_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define PSNIP_SAFE_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define PSNIP_SAFE_LIKELY(expr) !!(expr) -# define PSNIP_SAFE_UNLIKELY(expr) !!(expr) -#endif /* defined(__GNUC__) */ - -#if !defined(PSNIP_SAFE_STATIC_INLINE) -# if defined(__GNUC__) -# define PSNIP_SAFE__COMPILER_ATTRIBUTES __attribute__((__unused__)) -# else -# define PSNIP_SAFE__COMPILER_ATTRIBUTES -# endif - -# if defined(HEDLEY_INLINE) -# define PSNIP_SAFE__INLINE HEDLEY_INLINE -# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -# define PSNIP_SAFE__INLINE inline -# elif defined(__GNUC_STDC_INLINE__) -# define PSNIP_SAFE__INLINE __inline__ -# elif defined(_MSC_VER) && _MSC_VER >= 1200 -# define PSNIP_SAFE__INLINE __inline -# else -# define PSNIP_SAFE__INLINE -# endif - -# define PSNIP_SAFE__FUNCTION PSNIP_SAFE__COMPILER_ATTRIBUTES static PSNIP_SAFE__INLINE -#endif - -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -# define psnip_safe_bool _Bool -#else -# define psnip_safe_bool int -#endif - -#if !defined(PSNIP_SAFE_NO_FIXED) -/* For maximum portability include the exact-int module from - portable snippets. */ -# if \ - !defined(psnip_int64_t) || !defined(psnip_uint64_t) || \ - !defined(psnip_int32_t) || !defined(psnip_uint32_t) || \ - !defined(psnip_int16_t) || !defined(psnip_uint16_t) || \ - !defined(psnip_int8_t) || !defined(psnip_uint8_t) -# include -# if !defined(psnip_int64_t) -# define psnip_int64_t int64_t -# endif -# if !defined(psnip_uint64_t) -# define psnip_uint64_t uint64_t -# endif -# if !defined(psnip_int32_t) -# define psnip_int32_t int32_t -# endif -# if !defined(psnip_uint32_t) -# define psnip_uint32_t uint32_t -# endif -# if !defined(psnip_int16_t) -# define psnip_int16_t int16_t -# endif -# if !defined(psnip_uint16_t) -# define psnip_uint16_t uint16_t -# endif -# if !defined(psnip_int8_t) -# define psnip_int8_t int8_t -# endif -# if !defined(psnip_uint8_t) -# define psnip_uint8_t uint8_t -# endif -# endif -#endif /* !defined(PSNIP_SAFE_NO_FIXED) */ -#include -#include - -#if !defined(PSNIP_SAFE_SIZE_MAX) -# if defined(__SIZE_MAX__) -# define PSNIP_SAFE_SIZE_MAX __SIZE_MAX__ -# elif defined(PSNIP_EXACT_INT_HAVE_STDINT) -# include -# endif -#endif - -#if defined(PSNIP_SAFE_SIZE_MAX) -# define PSNIP_SAFE__SIZE_MAX_RT PSNIP_SAFE_SIZE_MAX -#else -# define PSNIP_SAFE__SIZE_MAX_RT (~((size_t) 0)) -#endif - -#if defined(PSNIP_SAFE_HAVE_INTSAFE_H) -/* In VS 10, stdint.h and intsafe.h both define (U)INTN_MIN/MAX, which - triggers warning C4005 (level 1). */ -# if defined(_MSC_VER) && (_MSC_VER == 1600) -# pragma warning(push) -# pragma warning(disable:4005) -# endif -# include -# if defined(_MSC_VER) && (_MSC_VER == 1600) -# pragma warning(pop) -# endif -#endif /* defined(PSNIP_SAFE_HAVE_INTSAFE_H) */ - -/* If there is a type larger than the one we're concerned with it's - * likely much faster to simply promote the operands, perform the - * requested operation, verify that the result falls within the - * original type, then cast the result back to the original type. */ - -#if !defined(PSNIP_SAFE_NO_PROMOTIONS) - -#define PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, op_name, op) \ - PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \ - psnip_safe_larger_##name##_##op_name (T a, T b) { \ - return ((psnip_safe_##name##_larger) a) op ((psnip_safe_##name##_larger) b); \ - } - -#define PSNIP_SAFE_DEFINE_LARGER_UNARY_OP(T, name, op_name, op) \ - PSNIP_SAFE__FUNCTION psnip_safe_##name##_larger \ - psnip_safe_larger_##name##_##op_name (T value) { \ - return (op ((psnip_safe_##name##_larger) value)); \ - } - -#define PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(T, name) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %) \ - PSNIP_SAFE_DEFINE_LARGER_UNARY_OP (T, name, neg, -) - -#define PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(T, name) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, add, +) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, sub, -) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mul, *) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, div, /) \ - PSNIP_SAFE_DEFINE_LARGER_BINARY_OP(T, name, mod, %) - -#define PSNIP_SAFE_IS_LARGER(ORIG_MAX, DEST_MAX) ((DEST_MAX / ORIG_MAX) >= ORIG_MAX) - -#if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__SIZEOF_INT128__) && !defined(__ibmxl__) -#define PSNIP_SAFE_HAVE_128 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" -typedef __int128 psnip_safe_int128_t; -typedef unsigned __int128 psnip_safe_uint128_t; -#pragma GCC diagnostic pop -#endif /* defined(__GNUC__) */ - -#if !defined(PSNIP_SAFE_NO_FIXED) -#define PSNIP_SAFE_HAVE_INT8_LARGER -#define PSNIP_SAFE_HAVE_UINT8_LARGER -typedef psnip_int16_t psnip_safe_int8_larger; -typedef psnip_uint16_t psnip_safe_uint8_larger; - -#define PSNIP_SAFE_HAVE_INT16_LARGER -typedef psnip_int32_t psnip_safe_int16_larger; -typedef psnip_uint32_t psnip_safe_uint16_larger; - -#define PSNIP_SAFE_HAVE_INT32_LARGER -typedef psnip_int64_t psnip_safe_int32_larger; -typedef psnip_uint64_t psnip_safe_uint32_larger; - -#if defined(PSNIP_SAFE_HAVE_128) -#define PSNIP_SAFE_HAVE_INT64_LARGER -typedef psnip_safe_int128_t psnip_safe_int64_larger; -typedef psnip_safe_uint128_t psnip_safe_uint64_larger; -#endif /* defined(PSNIP_SAFE_HAVE_128) */ -#endif /* !defined(PSNIP_SAFE_NO_FIXED) */ - -#define PSNIP_SAFE_HAVE_LARGER_SCHAR -#if PSNIP_SAFE_IS_LARGER(SCHAR_MAX, SHRT_MAX) -typedef short psnip_safe_schar_larger; -#elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, INT_MAX) -typedef int psnip_safe_schar_larger; -#elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LONG_MAX) -typedef long psnip_safe_schar_larger; -#elif PSNIP_SAFE_IS_LARGER(SCHAR_MAX, LLONG_MAX) -typedef long long psnip_safe_schar_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fff) -typedef psnip_int16_t psnip_safe_schar_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffLL) -typedef psnip_int32_t psnip_safe_schar_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SCHAR_MAX, 0x7fffffffffffffffLL) -typedef psnip_int64_t psnip_safe_schar_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SCHAR_MAX <= 0x7fffffffffffffffLL) -typedef psnip_safe_int128_t psnip_safe_schar_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_SCHAR -#endif - -#define PSNIP_SAFE_HAVE_LARGER_UCHAR -#if PSNIP_SAFE_IS_LARGER(UCHAR_MAX, USHRT_MAX) -typedef unsigned short psnip_safe_uchar_larger; -#elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, UINT_MAX) -typedef unsigned int psnip_safe_uchar_larger; -#elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULONG_MAX) -typedef unsigned long psnip_safe_uchar_larger; -#elif PSNIP_SAFE_IS_LARGER(UCHAR_MAX, ULLONG_MAX) -typedef unsigned long long psnip_safe_uchar_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffU) -typedef psnip_uint16_t psnip_safe_uchar_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffUL) -typedef psnip_uint32_t psnip_safe_uchar_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UCHAR_MAX, 0xffffffffffffffffULL) -typedef psnip_uint64_t psnip_safe_uchar_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UCHAR_MAX <= 0xffffffffffffffffULL) -typedef psnip_safe_uint128_t psnip_safe_uchar_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_UCHAR -#endif - -#if CHAR_MIN == 0 && defined(PSNIP_SAFE_HAVE_LARGER_UCHAR) -#define PSNIP_SAFE_HAVE_LARGER_CHAR -typedef psnip_safe_uchar_larger psnip_safe_char_larger; -#elif CHAR_MIN < 0 && defined(PSNIP_SAFE_HAVE_LARGER_SCHAR) -#define PSNIP_SAFE_HAVE_LARGER_CHAR -typedef psnip_safe_schar_larger psnip_safe_char_larger; -#endif - -#define PSNIP_SAFE_HAVE_LARGER_SHRT -#if PSNIP_SAFE_IS_LARGER(SHRT_MAX, INT_MAX) -typedef int psnip_safe_short_larger; -#elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LONG_MAX) -typedef long psnip_safe_short_larger; -#elif PSNIP_SAFE_IS_LARGER(SHRT_MAX, LLONG_MAX) -typedef long long psnip_safe_short_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fff) -typedef psnip_int16_t psnip_safe_short_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffLL) -typedef psnip_int32_t psnip_safe_short_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(SHRT_MAX, 0x7fffffffffffffffLL) -typedef psnip_int64_t psnip_safe_short_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (SHRT_MAX <= 0x7fffffffffffffffLL) -typedef psnip_safe_int128_t psnip_safe_short_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_SHRT -#endif - -#define PSNIP_SAFE_HAVE_LARGER_USHRT -#if PSNIP_SAFE_IS_LARGER(USHRT_MAX, UINT_MAX) -typedef unsigned int psnip_safe_ushort_larger; -#elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULONG_MAX) -typedef unsigned long psnip_safe_ushort_larger; -#elif PSNIP_SAFE_IS_LARGER(USHRT_MAX, ULLONG_MAX) -typedef unsigned long long psnip_safe_ushort_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffff) -typedef psnip_uint16_t psnip_safe_ushort_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffUL) -typedef psnip_uint32_t psnip_safe_ushort_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(USHRT_MAX, 0xffffffffffffffffULL) -typedef psnip_uint64_t psnip_safe_ushort_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (USHRT_MAX <= 0xffffffffffffffffULL) -typedef psnip_safe_uint128_t psnip_safe_ushort_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_USHRT -#endif - -#define PSNIP_SAFE_HAVE_LARGER_INT -#if PSNIP_SAFE_IS_LARGER(INT_MAX, LONG_MAX) -typedef long psnip_safe_int_larger; -#elif PSNIP_SAFE_IS_LARGER(INT_MAX, LLONG_MAX) -typedef long long psnip_safe_int_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fff) -typedef psnip_int16_t psnip_safe_int_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffLL) -typedef psnip_int32_t psnip_safe_int_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(INT_MAX, 0x7fffffffffffffffLL) -typedef psnip_int64_t psnip_safe_int_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (INT_MAX <= 0x7fffffffffffffffLL) -typedef psnip_safe_int128_t psnip_safe_int_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_INT -#endif - -#define PSNIP_SAFE_HAVE_LARGER_UINT -#if PSNIP_SAFE_IS_LARGER(UINT_MAX, ULONG_MAX) -typedef unsigned long psnip_safe_uint_larger; -#elif PSNIP_SAFE_IS_LARGER(UINT_MAX, ULLONG_MAX) -typedef unsigned long long psnip_safe_uint_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffff) -typedef psnip_uint16_t psnip_safe_uint_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffUL) -typedef psnip_uint32_t psnip_safe_uint_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(UINT_MAX, 0xffffffffffffffffULL) -typedef psnip_uint64_t psnip_safe_uint_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (UINT_MAX <= 0xffffffffffffffffULL) -typedef psnip_safe_uint128_t psnip_safe_uint_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_UINT -#endif - -#define PSNIP_SAFE_HAVE_LARGER_LONG -#if PSNIP_SAFE_IS_LARGER(LONG_MAX, LLONG_MAX) -typedef long long psnip_safe_long_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fff) -typedef psnip_int16_t psnip_safe_long_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffLL) -typedef psnip_int32_t psnip_safe_long_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LONG_MAX, 0x7fffffffffffffffLL) -typedef psnip_int64_t psnip_safe_long_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LONG_MAX <= 0x7fffffffffffffffLL) -typedef psnip_safe_int128_t psnip_safe_long_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_LONG -#endif - -#define PSNIP_SAFE_HAVE_LARGER_ULONG -#if PSNIP_SAFE_IS_LARGER(ULONG_MAX, ULLONG_MAX) -typedef unsigned long long psnip_safe_ulong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffff) -typedef psnip_uint16_t psnip_safe_ulong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffUL) -typedef psnip_uint32_t psnip_safe_ulong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULONG_MAX, 0xffffffffffffffffULL) -typedef psnip_uint64_t psnip_safe_ulong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULONG_MAX <= 0xffffffffffffffffULL) -typedef psnip_safe_uint128_t psnip_safe_ulong_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_ULONG -#endif - -#define PSNIP_SAFE_HAVE_LARGER_LLONG -#if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fff) -typedef psnip_int16_t psnip_safe_llong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffLL) -typedef psnip_int32_t psnip_safe_llong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(LLONG_MAX, 0x7fffffffffffffffLL) -typedef psnip_int64_t psnip_safe_llong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (LLONG_MAX <= 0x7fffffffffffffffLL) -typedef psnip_safe_int128_t psnip_safe_llong_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_LLONG -#endif - -#define PSNIP_SAFE_HAVE_LARGER_ULLONG -#if !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffff) -typedef psnip_uint16_t psnip_safe_ullong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffUL) -typedef psnip_uint32_t psnip_safe_ullong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(ULLONG_MAX, 0xffffffffffffffffULL) -typedef psnip_uint64_t psnip_safe_ullong_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (ULLONG_MAX <= 0xffffffffffffffffULL) -typedef psnip_safe_uint128_t psnip_safe_ullong_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_ULLONG -#endif - -#if defined(PSNIP_SAFE_SIZE_MAX) -#define PSNIP_SAFE_HAVE_LARGER_SIZE -#if PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, USHRT_MAX) -typedef unsigned short psnip_safe_size_larger; -#elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, UINT_MAX) -typedef unsigned int psnip_safe_size_larger; -#elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULONG_MAX) -typedef unsigned long psnip_safe_size_larger; -#elif PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, ULLONG_MAX) -typedef unsigned long long psnip_safe_size_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffff) -typedef psnip_uint16_t psnip_safe_size_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffUL) -typedef psnip_uint32_t psnip_safe_size_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && PSNIP_SAFE_IS_LARGER(PSNIP_SAFE_SIZE_MAX, 0xffffffffffffffffULL) -typedef psnip_uint64_t psnip_safe_size_larger; -#elif !defined(PSNIP_SAFE_NO_FIXED) && defined(PSNIP_SAFE_HAVE_128) && (PSNIP_SAFE_SIZE_MAX <= 0xffffffffffffffffULL) -typedef psnip_safe_uint128_t psnip_safe_size_larger; -#else -#undef PSNIP_SAFE_HAVE_LARGER_SIZE -#endif -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_SCHAR) -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(signed char, schar) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_UCHAR) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned char, uchar) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_CHAR) -#if CHAR_MIN == 0 -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(char, char) -#else -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(char, char) -#endif -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_SHORT) -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(short, short) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_USHORT) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned short, ushort) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_INT) -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(int, int) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_UINT) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned int, uint) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_LONG) -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long, long) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_ULONG) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long, ulong) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_LLONG) -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(long long, llong) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_ULLONG) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(unsigned long long, ullong) -#endif - -#if defined(PSNIP_SAFE_HAVE_LARGER_SIZE) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(size_t, size) -#endif - -#if !defined(PSNIP_SAFE_NO_FIXED) -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int8_t, int8) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint8_t, uint8) -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int16_t, int16) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint16_t, uint16) -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int32_t, int32) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint32_t, uint32) -#if defined(PSNIP_SAFE_HAVE_128) -PSNIP_SAFE_DEFINE_LARGER_SIGNED_OPS(psnip_int64_t, int64) -PSNIP_SAFE_DEFINE_LARGER_UNSIGNED_OPS(psnip_uint64_t, uint64) -#endif -#endif - -#endif /* !defined(PSNIP_SAFE_NO_PROMOTIONS) */ - -#define PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(T, name, op_name) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_##op_name(T* res, T a, T b) { \ - return !__builtin_##op_name##_overflow(a, b, res); \ - } - -#define PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(T, name, op_name, min, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_##op_name(T* res, T a, T b) { \ - const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \ - *res = (T) r; \ - return (r >= min) && (r <= max); \ - } - -#define PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(T, name, op_name, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_##op_name(T* res, T a, T b) { \ - const psnip_safe_##name##_larger r = psnip_safe_larger_##name##_##op_name(a, b); \ - *res = (T) r; \ - return (r <= max); \ - } - -#define PSNIP_SAFE_DEFINE_SIGNED_ADD(T, name, min, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_add (T* res, T a, T b) { \ - psnip_safe_bool r = !( ((b > 0) && (a > (max - b))) || \ - ((b < 0) && (a < (min - b))) ); \ - if(PSNIP_SAFE_LIKELY(r)) \ - *res = a + b; \ - return r; \ - } - -#define PSNIP_SAFE_DEFINE_UNSIGNED_ADD(T, name, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_add (T* res, T a, T b) { \ - *res = (T) (a + b); \ - return !PSNIP_SAFE_UNLIKELY((b > 0) && (a > (max - b))); \ - } - -#define PSNIP_SAFE_DEFINE_SIGNED_SUB(T, name, min, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_sub (T* res, T a, T b) { \ - psnip_safe_bool r = !((b > 0 && a < (min + b)) || \ - (b < 0 && a > (max + b))); \ - if(PSNIP_SAFE_LIKELY(r)) \ - *res = a - b; \ - return r; \ - } - -#define PSNIP_SAFE_DEFINE_UNSIGNED_SUB(T, name, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_sub (T* res, T a, T b) { \ - *res = a - b; \ - return !PSNIP_SAFE_UNLIKELY(b > a); \ - } - -#define PSNIP_SAFE_DEFINE_SIGNED_MUL(T, name, min, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_mul (T* res, T a, T b) { \ - psnip_safe_bool r = 1; \ - if (a > 0) { \ - if (b > 0) { \ - if (a > (max / b)) { \ - r = 0; \ - } \ - } else { \ - if (b < (min / a)) { \ - r = 0; \ - } \ - } \ - } else { \ - if (b > 0) { \ - if (a < (min / b)) { \ - r = 0; \ - } \ - } else { \ - if ( (a != 0) && (b < (max / a))) { \ - r = 0; \ - } \ - } \ - } \ - if(PSNIP_SAFE_LIKELY(r)) \ - *res = a * b; \ - return r; \ - } - -#define PSNIP_SAFE_DEFINE_UNSIGNED_MUL(T, name, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_mul (T* res, T a, T b) { \ - *res = (T) (a * b); \ - return !PSNIP_SAFE_UNLIKELY((a > 0) && (b > 0) && (a > (max / b))); \ - } - -#define PSNIP_SAFE_DEFINE_SIGNED_DIV(T, name, min, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_div (T* res, T a, T b) { \ - if (PSNIP_SAFE_UNLIKELY(b == 0)) { \ - *res = 0; \ - return 0; \ - } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \ - *res = min; \ - return 0; \ - } else { \ - *res = (T) (a / b); \ - return 1; \ - } \ - } - -#define PSNIP_SAFE_DEFINE_UNSIGNED_DIV(T, name, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_div (T* res, T a, T b) { \ - if (PSNIP_SAFE_UNLIKELY(b == 0)) { \ - *res = 0; \ - return 0; \ - } else { \ - *res = a / b; \ - return 1; \ - } \ - } - -#define PSNIP_SAFE_DEFINE_SIGNED_MOD(T, name, min, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_mod (T* res, T a, T b) { \ - if (PSNIP_SAFE_UNLIKELY(b == 0)) { \ - *res = 0; \ - return 0; \ - } else if (PSNIP_SAFE_UNLIKELY(a == min && b == -1)) { \ - *res = min; \ - return 0; \ - } else { \ - *res = (T) (a % b); \ - return 1; \ - } \ - } - -#define PSNIP_SAFE_DEFINE_UNSIGNED_MOD(T, name, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_mod (T* res, T a, T b) { \ - if (PSNIP_SAFE_UNLIKELY(b == 0)) { \ - *res = 0; \ - return 0; \ - } else { \ - *res = a % b; \ - return 1; \ - } \ - } - -#define PSNIP_SAFE_DEFINE_SIGNED_NEG(T, name, min, max) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_neg (T* res, T value) { \ - psnip_safe_bool r = value != min; \ - *res = PSNIP_SAFE_LIKELY(r) ? -value : max; \ - return r; \ - } - -#define PSNIP_SAFE_DEFINE_INTSAFE(T, name, op, isf) \ - PSNIP_SAFE__FUNCTION psnip_safe_bool \ - psnip_safe_##name##_##op (T* res, T a, T b) { \ - return isf(a, b, res) == S_OK; \ - } - -#if CHAR_MIN == 0 -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, add, CHAR_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, sub, CHAR_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(char, char, mul, CHAR_MAX) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(char, char, CHAR_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(char, char, CHAR_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(char, char, CHAR_MAX) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(char, char, CHAR_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(char, char, CHAR_MAX) -#else /* CHAR_MIN != 0 */ -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(char, char, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_CHAR) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, add, CHAR_MIN, CHAR_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, sub, CHAR_MIN, CHAR_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(char, char, mul, CHAR_MIN, CHAR_MAX) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(char, char, CHAR_MIN, CHAR_MAX) -PSNIP_SAFE_DEFINE_SIGNED_SUB(char, char, CHAR_MIN, CHAR_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MUL(char, char, CHAR_MIN, CHAR_MAX) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(char, char, CHAR_MIN, CHAR_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MOD(char, char, CHAR_MIN, CHAR_MAX) -PSNIP_SAFE_DEFINE_SIGNED_NEG(char, char, CHAR_MIN, CHAR_MAX) -#endif - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(signed char, schar, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_SCHAR) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, add, SCHAR_MIN, SCHAR_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, sub, SCHAR_MIN, SCHAR_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(signed char, schar, mul, SCHAR_MIN, SCHAR_MAX) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(signed char, schar, SCHAR_MIN, SCHAR_MAX) -PSNIP_SAFE_DEFINE_SIGNED_SUB(signed char, schar, SCHAR_MIN, SCHAR_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MUL(signed char, schar, SCHAR_MIN, SCHAR_MAX) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(signed char, schar, SCHAR_MIN, SCHAR_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MOD(signed char, schar, SCHAR_MIN, SCHAR_MAX) -PSNIP_SAFE_DEFINE_SIGNED_NEG(signed char, schar, SCHAR_MIN, SCHAR_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned char, uchar, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_UCHAR) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, add, UCHAR_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, sub, UCHAR_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned char, uchar, mul, UCHAR_MAX) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned char, uchar, UCHAR_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned char, uchar, UCHAR_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned char, uchar, UCHAR_MAX) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned char, uchar, UCHAR_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned char, uchar, UCHAR_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(short, short, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_SHORT) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, add, SHRT_MIN, SHRT_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, sub, SHRT_MIN, SHRT_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(short, short, mul, SHRT_MIN, SHRT_MAX) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(short, short, SHRT_MIN, SHRT_MAX) -PSNIP_SAFE_DEFINE_SIGNED_SUB(short, short, SHRT_MIN, SHRT_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MUL(short, short, SHRT_MIN, SHRT_MAX) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(short, short, SHRT_MIN, SHRT_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MOD(short, short, SHRT_MIN, SHRT_MAX) -PSNIP_SAFE_DEFINE_SIGNED_NEG(short, short, SHRT_MIN, SHRT_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned short, ushort, mul) -#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) -PSNIP_SAFE_DEFINE_INTSAFE(USHORT, ushort, add, UShortAdd) -PSNIP_SAFE_DEFINE_INTSAFE(USHORT, ushort, sub, UShortSub) -PSNIP_SAFE_DEFINE_INTSAFE(USHORT, ushort, mul, UShortMult) -#elif defined(PSNIP_SAFE_HAVE_LARGER_USHORT) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, add, USHRT_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, sub, USHRT_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned short, ushort, mul, USHRT_MAX) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned short, ushort, USHRT_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned short, ushort, USHRT_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned short, ushort, USHRT_MAX) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned short, ushort, USHRT_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned short, ushort, USHRT_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(int, int, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_INT) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, add, INT_MIN, INT_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, sub, INT_MIN, INT_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(int, int, mul, INT_MIN, INT_MAX) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(int, int, INT_MIN, INT_MAX) -PSNIP_SAFE_DEFINE_SIGNED_SUB(int, int, INT_MIN, INT_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MUL(int, int, INT_MIN, INT_MAX) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(int, int, INT_MIN, INT_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MOD(int, int, INT_MIN, INT_MAX) -PSNIP_SAFE_DEFINE_SIGNED_NEG(int, int, INT_MIN, INT_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned int, uint, mul) -#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) -PSNIP_SAFE_DEFINE_INTSAFE(UINT, uint, add, UIntAdd) -PSNIP_SAFE_DEFINE_INTSAFE(UINT, uint, sub, UIntSub) -PSNIP_SAFE_DEFINE_INTSAFE(UINT, uint, mul, UIntMult) -#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, add, UINT_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, sub, UINT_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned int, uint, mul, UINT_MAX) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned int, uint, UINT_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned int, uint, UINT_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned int, uint, UINT_MAX) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned int, uint, UINT_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned int, uint, UINT_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long, long, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_LONG) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, add, LONG_MIN, LONG_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, sub, LONG_MIN, LONG_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long, long, mul, LONG_MIN, LONG_MAX) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(long, long, LONG_MIN, LONG_MAX) -PSNIP_SAFE_DEFINE_SIGNED_SUB(long, long, LONG_MIN, LONG_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MUL(long, long, LONG_MIN, LONG_MAX) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(long, long, LONG_MIN, LONG_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MOD(long, long, LONG_MIN, LONG_MAX) -PSNIP_SAFE_DEFINE_SIGNED_NEG(long, long, LONG_MIN, LONG_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long, ulong, mul) -#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) -PSNIP_SAFE_DEFINE_INTSAFE(ULONG, ulong, add, ULongAdd) -PSNIP_SAFE_DEFINE_INTSAFE(ULONG, ulong, sub, ULongSub) -PSNIP_SAFE_DEFINE_INTSAFE(ULONG, ulong, mul, ULongMult) -#elif defined(PSNIP_SAFE_HAVE_LARGER_ULONG) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, add, ULONG_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, sub, ULONG_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long, ulong, mul, ULONG_MAX) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long, ulong, ULONG_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long, ulong, ULONG_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long, ulong, ULONG_MAX) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long, ulong, ULONG_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long, ulong, ULONG_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(long long, llong, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_LLONG) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, add, LLONG_MIN, LLONG_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, sub, LLONG_MIN, LLONG_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(long long, llong, mul, LLONG_MIN, LLONG_MAX) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(long long, llong, LLONG_MIN, LLONG_MAX) -PSNIP_SAFE_DEFINE_SIGNED_SUB(long long, llong, LLONG_MIN, LLONG_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MUL(long long, llong, LLONG_MIN, LLONG_MAX) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(long long, llong, LLONG_MIN, LLONG_MAX) -PSNIP_SAFE_DEFINE_SIGNED_MOD(long long, llong, LLONG_MIN, LLONG_MAX) -PSNIP_SAFE_DEFINE_SIGNED_NEG(long long, llong, LLONG_MIN, LLONG_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(unsigned long long, ullong, mul) -#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) -PSNIP_SAFE_DEFINE_INTSAFE(ULONGLONG, ullong, add, ULongLongAdd) -PSNIP_SAFE_DEFINE_INTSAFE(ULONGLONG, ullong, sub, ULongLongSub) -PSNIP_SAFE_DEFINE_INTSAFE(ULONGLONG, ullong, mul, ULongLongMult) -#elif defined(PSNIP_SAFE_HAVE_LARGER_ULLONG) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, add, ULLONG_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, sub, ULLONG_MAX) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(unsigned long long, ullong, mul, ULLONG_MAX) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(unsigned long long, ullong, ULLONG_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(unsigned long long, ullong, ULLONG_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(unsigned long long, ullong, ULLONG_MAX) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(unsigned long long, ullong, ULLONG_MAX) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(unsigned long long, ullong, ULLONG_MAX) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(size_t, size, mul) -#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) -PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, add, SizeTAdd) -PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, sub, SizeTSub) -PSNIP_SAFE_DEFINE_INTSAFE(size_t, size, mul, SizeTMult) -#elif defined(PSNIP_SAFE_HAVE_LARGER_SIZE) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, add, PSNIP_SAFE__SIZE_MAX_RT) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, sub, PSNIP_SAFE__SIZE_MAX_RT) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(size_t, size, mul, PSNIP_SAFE__SIZE_MAX_RT) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(size_t, size, PSNIP_SAFE__SIZE_MAX_RT) - -#if !defined(PSNIP_SAFE_NO_FIXED) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int8_t, int8, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_INT8) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, add, (-0x7fLL-1), 0x7f) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, sub, (-0x7fLL-1), 0x7f) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int8_t, int8, mul, (-0x7fLL-1), 0x7f) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) -PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) -PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) -PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) -PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int8_t, int8, (-0x7fLL-1), 0x7f) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint8_t, uint8, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT8) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, add, 0xff) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, sub, 0xff) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint8_t, uint8, mul, 0xff) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint8_t, uint8, 0xff) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint8_t, uint8, 0xff) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint8_t, uint8, 0xff) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint8_t, uint8, 0xff) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint8_t, uint8, 0xff) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int16_t, int16, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_INT16) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, add, (-32767-1), 0x7fff) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, sub, (-32767-1), 0x7fff) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int16_t, int16, mul, (-32767-1), 0x7fff) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int16_t, int16, (-32767-1), 0x7fff) -PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int16_t, int16, (-32767-1), 0x7fff) -PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int16_t, int16, (-32767-1), 0x7fff) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int16_t, int16, (-32767-1), 0x7fff) -PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int16_t, int16, (-32767-1), 0x7fff) -PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int16_t, int16, (-32767-1), 0x7fff) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint16_t, uint16, mul) -#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32) -PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, add, UShortAdd) -PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, sub, UShortSub) -PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint16_t, uint16, mul, UShortMult) -#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT16) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, add, 0xffff) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, sub, 0xffff) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint16_t, uint16, mul, 0xffff) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint16_t, uint16, 0xffff) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint16_t, uint16, 0xffff) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint16_t, uint16, 0xffff) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint16_t, uint16, 0xffff) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint16_t, uint16, 0xffff) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int32_t, int32, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_INT32) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, add, (-0x7fffffffLL-1), 0x7fffffffLL) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, sub, (-0x7fffffffLL-1), 0x7fffffffLL) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int32_t, int32, mul, (-0x7fffffffLL-1), 0x7fffffffLL) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) -PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) -PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) -PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) -PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffLL) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint32_t, uint32, mul) -#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32) -PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, add, UIntAdd) -PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, sub, UIntSub) -PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint32_t, uint32, mul, UIntMult) -#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT32) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, add, 0xffffffffUL) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, sub, 0xffffffffUL) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint32_t, uint32, mul, 0xffffffffUL) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint32_t, uint32, 0xffffffffUL) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint32_t, uint32, 0xffffffffUL) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint32_t, uint32, 0xffffffffUL) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint32_t, uint32, 0xffffffffUL) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint32_t, uint32, 0xffffffffUL) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_int64_t, int64, mul) -#elif defined(PSNIP_SAFE_HAVE_LARGER_INT64) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, add, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, sub, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) -PSNIP_SAFE_DEFINE_PROMOTED_SIGNED_BINARY_OP(psnip_int64_t, int64, mul, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) -#else -PSNIP_SAFE_DEFINE_SIGNED_ADD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) -PSNIP_SAFE_DEFINE_SIGNED_SUB(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) -PSNIP_SAFE_DEFINE_SIGNED_MUL(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) -#endif -PSNIP_SAFE_DEFINE_SIGNED_DIV(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) -PSNIP_SAFE_DEFINE_SIGNED_MOD(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) -PSNIP_SAFE_DEFINE_SIGNED_NEG(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, add) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, sub) -PSNIP_SAFE_DEFINE_BUILTIN_BINARY_OP(psnip_uint64_t, uint64, mul) -#elif defined(PSNIP_SAFE_HAVE_INTSAFE_H) && defined(_WIN32) -PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, add, ULongLongAdd) -PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, sub, ULongLongSub) -PSNIP_SAFE_DEFINE_INTSAFE(psnip_uint64_t, uint64, mul, ULongLongMult) -#elif defined(PSNIP_SAFE_HAVE_LARGER_UINT64) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, add, 0xffffffffffffffffULL) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, sub, 0xffffffffffffffffULL) -PSNIP_SAFE_DEFINE_PROMOTED_UNSIGNED_BINARY_OP(psnip_uint64_t, uint64, mul, 0xffffffffffffffffULL) -#else -PSNIP_SAFE_DEFINE_UNSIGNED_ADD(psnip_uint64_t, uint64, 0xffffffffffffffffULL) -PSNIP_SAFE_DEFINE_UNSIGNED_SUB(psnip_uint64_t, uint64, 0xffffffffffffffffULL) -PSNIP_SAFE_DEFINE_UNSIGNED_MUL(psnip_uint64_t, uint64, 0xffffffffffffffffULL) -#endif -PSNIP_SAFE_DEFINE_UNSIGNED_DIV(psnip_uint64_t, uint64, 0xffffffffffffffffULL) -PSNIP_SAFE_DEFINE_UNSIGNED_MOD(psnip_uint64_t, uint64, 0xffffffffffffffffULL) - -#endif /* !defined(PSNIP_SAFE_NO_FIXED) */ - -#define PSNIP_SAFE_C11_GENERIC_SELECTION(res, op) \ - _Generic((*res), \ - char: psnip_safe_char_##op, \ - unsigned char: psnip_safe_uchar_##op, \ - short: psnip_safe_short_##op, \ - unsigned short: psnip_safe_ushort_##op, \ - int: psnip_safe_int_##op, \ - unsigned int: psnip_safe_uint_##op, \ - long: psnip_safe_long_##op, \ - unsigned long: psnip_safe_ulong_##op, \ - long long: psnip_safe_llong_##op, \ - unsigned long long: psnip_safe_ullong_##op) - -#define PSNIP_SAFE_C11_GENERIC_BINARY_OP(op, res, a, b) \ - PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, a, b) -#define PSNIP_SAFE_C11_GENERIC_UNARY_OP(op, res, v) \ - PSNIP_SAFE_C11_GENERIC_SELECTION(res, op)(res, v) - -#if defined(PSNIP_SAFE_HAVE_BUILTIN_OVERFLOW) -#define psnip_safe_add(res, a, b) !__builtin_add_overflow(a, b, res) -#define psnip_safe_sub(res, a, b) !__builtin_sub_overflow(a, b, res) -#define psnip_safe_mul(res, a, b) !__builtin_mul_overflow(a, b, res) -#define psnip_safe_div(res, a, b) !__builtin_div_overflow(a, b, res) -#define psnip_safe_mod(res, a, b) !__builtin_mod_overflow(a, b, res) -#define psnip_safe_neg(res, v) PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v) - -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) -/* The are no fixed-length or size selections because they cause an - * error about _Generic specifying two compatible types. Hopefully - * this doesn't cause problems on exotic platforms, but if it does - * please let me know and I'll try to figure something out. */ - -#define psnip_safe_add(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(add, res, a, b) -#define psnip_safe_sub(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(sub, res, a, b) -#define psnip_safe_mul(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mul, res, a, b) -#define psnip_safe_div(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(div, res, a, b) -#define psnip_safe_mod(res, a, b) PSNIP_SAFE_C11_GENERIC_BINARY_OP(mod, res, a, b) -#define psnip_safe_neg(res, v) PSNIP_SAFE_C11_GENERIC_UNARY_OP (neg, res, v) -#endif - -#if !defined(PSNIP_SAFE_HAVE_BUILTINS) && (defined(PSNIP_SAFE_EMULATE_NATIVE) || defined(PSNIP_BUILTIN_EMULATE_NATIVE)) -# define __builtin_sadd_overflow(a, b, res) (!psnip_safe_int_add(res, a, b)) -# define __builtin_saddl_overflow(a, b, res) (!psnip_safe_long_add(res, a, b)) -# define __builtin_saddll_overflow(a, b, res) (!psnip_safe_llong_add(res, a, b)) -# define __builtin_uadd_overflow(a, b, res) (!psnip_safe_uint_add(res, a, b)) -# define __builtin_uaddl_overflow(a, b, res) (!psnip_safe_ulong_add(res, a, b)) -# define __builtin_uaddll_overflow(a, b, res) (!psnip_safe_ullong_add(res, a, b)) - -# define __builtin_ssub_overflow(a, b, res) (!psnip_safe_int_sub(res, a, b)) -# define __builtin_ssubl_overflow(a, b, res) (!psnip_safe_long_sub(res, a, b)) -# define __builtin_ssubll_overflow(a, b, res) (!psnip_safe_llong_sub(res, a, b)) -# define __builtin_usub_overflow(a, b, res) (!psnip_safe_uint_sub(res, a, b)) -# define __builtin_usubl_overflow(a, b, res) (!psnip_safe_ulong_sub(res, a, b)) -# define __builtin_usubll_overflow(a, b, res) (!psnip_safe_ullong_sub(res, a, b)) - -# define __builtin_smul_overflow(a, b, res) (!psnip_safe_int_mul(res, a, b)) -# define __builtin_smull_overflow(a, b, res) (!psnip_safe_long_mul(res, a, b)) -# define __builtin_smulll_overflow(a, b, res) (!psnip_safe_llong_mul(res, a, b)) -# define __builtin_umul_overflow(a, b, res) (!psnip_safe_uint_mul(res, a, b)) -# define __builtin_umull_overflow(a, b, res) (!psnip_safe_ulong_mul(res, a, b)) -# define __builtin_umulll_overflow(a, b, res) (!psnip_safe_ullong_mul(res, a, b)) -#endif - -#endif /* !defined(PSNIP_SAFE_H) */ diff --git a/ModelicaExternalC/C-Sources/snprintf.c b/ModelicaExternalC/C-Sources/snprintf.c deleted file mode 100644 index b21652234..000000000 --- a/ModelicaExternalC/C-Sources/snprintf.c +++ /dev/null @@ -1,1572 +0,0 @@ -/* - * Copyright (c) 1995 Patrick Powell. - * - * This code is based on code written by Patrick Powell . - * It may be used for any purpose as long as this notice remains intact on all - * source code distributions. - */ - -/* - * Copyright (c) 2008 Holger Weiss. - * - * This version of the code is maintained by Holger Weiss . - * My changes to the code may freely be used, modified and/or redistributed for - * any purpose. It would be nice if additions and fixes to this file (including - * trivial code cleanups) would be sent back in order to let me include them in - * the version available at . - * However, this is not a requirement for using or redistributing (possibly - * modified) versions of this file, nor is leaving this notice intact mandatory. - */ - -/* - * History - * - * 2008-01-20 Holger Weiss for C99-snprintf 1.1: - * - * Fixed the detection of infinite floating point values on IRIX (and - * possibly other systems) and applied another few minor cleanups. - * - * 2008-01-06 Holger Weiss for C99-snprintf 1.0: - * - * Added a lot of new features, fixed many bugs, and incorporated various - * improvements done by Andrew Tridgell , Russ Allbery - * , Hrvoje Niksic , Damien Miller - * , and others for the Samba, INN, Wget, and OpenSSH - * projects. The additions include: support the "e", "E", "g", "G", and - * "F" conversion specifiers (and use conversion style "f" or "F" for the - * still unsupported "a" and "A" specifiers); support the "hh", "ll", "j", - * "t", and "z" length modifiers; support the "#" flag and the (non-C99) - * "'" flag; use localeconv(3) (if available) to get both the current - * locale's decimal point character and the separator between groups of - * digits; fix the handling of various corner cases of field width and - * precision specifications; fix various floating point conversion bugs; - * handle infinite and NaN floating point values; don't attempt to write to - * the output buffer (which may be NULL) if a size of zero was specified; - * check for integer overflow of the field width, precision, and return - * values and during the floating point conversion; use the OUTCHAR() macro - * instead of a function for better performance; provide asprintf(3) and - * vasprintf(3) functions; add new test cases. The replacement functions - * have been renamed to use an "rpl_" prefix, the function calls in the - * main project (and in this file) must be redefined accordingly for each - * replacement function which is needed (by using Autoconf or other means). - * Various other minor improvements have been applied and the coding style - * was cleaned up for consistency. - * - * 2007-07-23 Holger Weiss for Mutt 1.5.13: - * - * C99 compliant snprintf(3) and vsnprintf(3) functions return the number - * of characters that would have been written to a sufficiently sized - * buffer (excluding the '\0'). The original code simply returned the - * length of the resulting output string, so that's been fixed. - * - * 1998-03-05 Michael Elkins for Mutt 0.90.8: - * - * The original code assumed that both snprintf(3) and vsnprintf(3) were - * missing. Some systems only have snprintf(3) but not vsnprintf(3), so - * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. - * - * 1998-01-27 Thomas Roessler for Mutt 0.89i: - * - * The PGP code was using unsigned hexadecimal formats. Unfortunately, - * unsigned formats simply didn't work. - * - * 1997-10-22 Brandon Long for Mutt 0.87.1: - * - * Ok, added some minimal floating point support, which means this probably - * requires libm on most operating systems. Don't yet support the exponent - * (e,E) and sigfig (g,G). Also, fmtint() was pretty badly broken, it just - * wasn't being exercised in ways which showed it, so that's been fixed. - * Also, formatted the code to Mutt conventions, and removed dead code left - * over from the original. Also, there is now a builtin-test, run with: - * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm && ./snprintf - * - * 2996-09-15 Brandon Long for Mutt 0.43: - * - * This was ugly. It is still ugly. I opted out of floating point - * numbers, but the formatter understands just about everything from the - * normal C string format, at least as far as I can tell from the Solaris - * 2.5 printf(3S) man page. - */ - -/* - * ToDo - * - * - Add wide character support. - * - Add support for "%a" and "%A" conversions. - * - Create test routines which predefine the expected results. Our test cases - * usually expose bugs in system implementations rather than in ours :-) - */ - -/* - * Usage - * - * 1) The following preprocessor macros should be defined to 1 if the feature or - * file in question is available on the target system (by using Autoconf or - * other means), though basic functionality should be available as long as - * HAVE_STDARG_H and HAVE_STDLIB_H are defined correctly: - * - * HAVE_VSNPRINTF - * HAVE_SNPRINTF - * HAVE_VASPRINTF - * HAVE_ASPRINTF - * HAVE_STDARG_H - * HAVE_STDDEF_H - * HAVE_STDINT_H - * HAVE_STDLIB_H - * HAVE_INTTYPES_H - * HAVE_LOCALE_H - * HAVE_LOCALECONV - * HAVE_LCONV_DECIMAL_POINT - * HAVE_LCONV_THOUSANDS_SEP - * HAVE_LONG_DOUBLE - * HAVE_LONG_LONG_INT - * HAVE_UNSIGNED_LONG_LONG_INT - * HAVE_INTMAX_T - * HAVE_UINTMAX_T - * HAVE_UINTPTR_T - * HAVE_PTRDIFF_T - * HAVE_VA_COPY - * HAVE___VA_COPY - * - * 2) The calls to the functions which should be replaced must be redefined - * throughout the project files (by using Autoconf or other means): - * - * #define vsnprintf rpl_vsnprintf - * #define snprintf rpl_snprintf - * #define vasprintf rpl_vasprintf - * #define asprintf rpl_asprintf - * - * 3) The required replacement functions should be declared in some header file - * included throughout the project files: - * - * #if HAVE_CONFIG_H - * #include - * #endif - * #if HAVE_STDARG_H - * #include - * #if !HAVE_VSNPRINTF - * int rpl_vsnprintf(char *, size_t, const char *, va_list); - * #endif - * #if !HAVE_SNPRINTF - * int rpl_snprintf(char *, size_t, const char *, ...); - * #endif - * #if !HAVE_VASPRINTF - * int rpl_vasprintf(char **, const char *, va_list); - * #endif - * #if !HAVE_ASPRINTF - * int rpl_asprintf(char **, const char *, ...); - * #endif - * #endif - * - * Autoconf macros for handling step 1 and step 2 are available at - * . - */ - - -#ifndef HAVE_STDARG_H -#define HAVE_STDARG_H 1 -#endif -#ifndef HAVE_STDLIB_H -#define HAVE_STDLIB_H 1 -#endif - -/* Define to 1 if you have a C99 compliant `snprintf' function. */ -#if defined(STDC99) -#define HAVE_SNPRINTF 1 -#elif defined(__MINGW32__) || defined(__CYGWIN__) -#if __STDC_VERSION__ >= 199901L -#define HAVE_SNPRINTF 1 -#endif -#elif defined(__WATCOMC__) -#define HAVE_SNPRINTF 1 -#elif defined(__TURBOC__) && __TURBOC__ >= 0x550 -#define HAVE_SNPRINTF 1 -#elif defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -#define HAVE_SNPRINTF 1 -#elif defined(_MSC_VER) && _MSC_VER >= 1900 -#define HAVE_SNPRINTF 1 -#else -#undef HAVE_SNPRINTF -#endif - -/* Define to 1 if you have a C99 compliant `vsnprintf' function. */ -#if defined(STDC99) -#define HAVE_VSNPRINTF 1 -#elif defined(__MINGW32__) || defined(__CYGWIN__) -#if __STDC_VERSION__ >= 199901L -#define HAVE_VSNPRINTF 1 -#endif -#elif defined(__WATCOMC__) -#define HAVE_VSNPRINTF 1 -#elif defined(__TURBOC__) && __TURBOC__ >= 0x550 -#define HAVE_VSNPRINTF 1 -#elif defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -#define HAVE_VSNPRINTF 1 -#elif defined(_MSC_VER) && _MSC_VER >= 1900 -#define HAVE_VSNPRINTF 1 -#else -#undef HAVE_VSNPRINTF -#endif - -/* Define to 1 if you have the `asprintf' function. */ -#if defined(__CYGWIN__) || defined(__gnu_linux__) -#define HAVE_ASPRINTF 1 -#else -#undef HAVE_ASPRINTF -#endif - -/* Define to 1 if you have the `vasprintf' function. */ -#if defined(__CYGWIN__) || defined(__gnu_linux__) -#define HAVE_VASPRINTF 1 -#else -#undef HAVE_VASPRINTF -#endif - - -/* Define to 1 if you have the header file. */ -#if defined(_WIN32) -#if defined(_MSC_VER) && _MSC_VER >= 1600 -#define HAVE_STDINT_H 1 -#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) -#define HAVE_STDINT_H 1 -#else -#undef HAVE_STDINT_H -#endif -#elif defined(__GNUC__) && !defined(__VXWORKS__) -#define HAVE_STDINT_H 1 -#else -#undef HAVE_STDINT_H -#endif - -/* Define to 1 if the system has the type `intmax_t'. */ -#if defined(_WIN32) -#if defined(_MSC_VER) && _MSC_VER >= 1600 -#define HAVE_INTMAX_T 1 -#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) -#define HAVE_INTMAX_T 1 -#else -#undef HAVE_INTMAX_T -#endif -#elif defined(__GNUC__) && !defined(__VXWORKS__) -#define HAVE_INTMAX_T 1 -#else -#undef HAVE_INTMAX_T -#endif - -/* Define to 1 if the system has the type `uintmax_t'. */ -#if defined(_WIN32) -#if defined(_MSC_VER) && _MSC_VER >= 1600 -#define HAVE_UINTMAX_T 1 -#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) -#define HAVE_UINTMAX_T 1 -#else -#undef HAVE_UINTMAX_T -#endif -#elif defined(__GNUC__) && !defined(__VXWORKS__) -#define HAVE_UINTMAX_T 1 -#else -#undef HAVE_UINTMAX_T -#endif - -/* Define to 1 if the system has the type `uintptr_t'. */ -#if defined(__LCC__) || (defined(_MSC_VER) && _MSC_VER <= 1200) -#undef HAVE_UINTPTR_T -#else -#define HAVE_UINTPTR_T 1 -#endif - -#if !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || !HAVE_VASPRINTF -#include /* For NULL, size_t, vsnprintf(3), and vasprintf(3). */ -#ifdef VA_START -#undef VA_START -#endif /* defined(VA_START) */ -#ifdef VA_SHIFT -#undef VA_SHIFT -#endif /* defined(VA_SHIFT) */ -#if HAVE_STDARG_H -#include -#define VA_START(ap, last) va_start(ap, last) -#define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */ -#else /* Assume is available. */ -#include -#define VA_START(ap, last) va_start(ap) /* "last" is ignored. */ -#define VA_SHIFT(ap, value, type) value = va_arg(ap, type) -#endif /* HAVE_STDARG_H */ - -#if !HAVE_VASPRINTF -#if HAVE_STDLIB_H -#include /* For malloc(3). */ -#endif /* HAVE_STDLIB_H */ -#ifdef VA_COPY -#undef VA_COPY -#endif /* defined(VA_COPY) */ -#ifdef VA_END_COPY -#undef VA_END_COPY -#endif /* defined(VA_END_COPY) */ -#if HAVE_VA_COPY -#define VA_COPY(dest, src) va_copy(dest, src) -#define VA_END_COPY(ap) va_end(ap) -#elif HAVE___VA_COPY -#define VA_COPY(dest, src) __va_copy(dest, src) -#define VA_END_COPY(ap) va_end(ap) -#else -#define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list)) -#define VA_END_COPY(ap) /* No-op. */ -#define NEED_MYMEMCPY 1 -static void *mymemcpy(void *, void *, size_t); -#endif /* HAVE_VA_COPY */ -#endif /* !HAVE_VASPRINTF */ - -#if !HAVE_VSNPRINTF -#include /* For ERANGE and errno. */ -#include /* For *_MAX. */ -#if HAVE_INTTYPES_H -#include /* For intmax_t (if not defined in ). */ -#endif /* HAVE_INTTYPES_H */ -#if HAVE_LOCALE_H -#include /* For localeconv(3). */ -#endif /* HAVE_LOCALE_H */ -#if HAVE_STDDEF_H -#include /* For ptrdiff_t. */ -#endif /* HAVE_STDDEF_H */ -#if HAVE_STDINT_H -#include /* For intmax_t. */ -#endif /* HAVE_STDINT_H */ - -/* Support for unsigned long long int. We may also need ULLONG_MAX. */ -#ifndef ULONG_MAX /* We may need ULONG_MAX as a fallback. */ -#ifdef UINT_MAX -#define ULONG_MAX UINT_MAX -#else -#define ULONG_MAX INT_MAX -#endif /* defined(UINT_MAX) */ -#endif /* !defined(ULONG_MAX) */ -#ifdef ULLONG -#undef ULLONG -#endif /* defined(ULLONG) */ -#if HAVE_UNSIGNED_LONG_LONG_INT -#define ULLONG unsigned long long int -#ifndef ULLONG_MAX -#define ULLONG_MAX ULONG_MAX -#endif /* !defined(ULLONG_MAX) */ -#else -#define ULLONG unsigned long int -#ifdef ULLONG_MAX -#undef ULLONG_MAX -#endif /* defined(ULLONG_MAX) */ -#define ULLONG_MAX ULONG_MAX -#endif /* HAVE_LONG_LONG_INT */ - -/* Support for uintmax_t. We also need UINTMAX_MAX. */ -#ifdef UINTMAX_T -#undef UINTMAX_T -#endif /* defined(UINTMAX_T) */ -#if HAVE_UINTMAX_T || defined(uintmax_t) -#define UINTMAX_T uintmax_t -#ifndef UINTMAX_MAX -#define UINTMAX_MAX ULLONG_MAX -#endif /* !defined(UINTMAX_MAX) */ -#else -#define UINTMAX_T ULLONG -#ifdef UINTMAX_MAX -#undef UINTMAX_MAX -#endif /* defined(UINTMAX_MAX) */ -#define UINTMAX_MAX ULLONG_MAX -#endif /* HAVE_UINTMAX_T || defined(uintmax_t) */ - -/* Support for long double. */ -#ifndef LDOUBLE -#if HAVE_LONG_DOUBLE -#define LDOUBLE long double -#else -#define LDOUBLE double -#endif /* HAVE_LONG_DOUBLE */ -#endif /* !defined(LDOUBLE) */ - -/* Support for long long int. */ -#ifndef LLONG -#if HAVE_LONG_LONG_INT -#define LLONG long long int -#else -#define LLONG long int -#endif /* HAVE_LONG_LONG_INT */ -#endif /* !defined(LLONG) */ - -/* Support for intmax_t. */ -#ifndef INTMAX_T -#if HAVE_INTMAX_T || defined(intmax_t) -#define INTMAX_T intmax_t -#else -#define INTMAX_T LLONG -#endif /* HAVE_INTMAX_T || defined(intmax_t) */ -#endif /* !defined(INTMAX_T) */ - -/* Support for uintptr_t. */ -#ifndef UINTPTR_T -#if HAVE_UINTPTR_T || defined(uintptr_t) -#define UINTPTR_T uintptr_t -#else -#define UINTPTR_T unsigned long int -#endif /* HAVE_UINTPTR_T || defined(uintptr_t) */ -#endif /* !defined(UINTPTR_T) */ - -/* Support for ptrdiff_t. */ -#ifndef PTRDIFF_T -#if HAVE_PTRDIFF_T || defined(ptrdiff_t) -#define PTRDIFF_T ptrdiff_t -#else -#define PTRDIFF_T long int -#endif /* HAVE_PTRDIFF_T || defined(ptrdiff_t) */ -#endif /* !defined(PTRDIFF_T) */ - -/* - * We need an unsigned integer type corresponding to ptrdiff_t (cf. C99: - * 7.19.6.1, 7). However, we'll simply use PTRDIFF_T and convert it to an - * unsigned type if necessary. This should work just fine in practice. - */ -#ifndef UPTRDIFF_T -#define UPTRDIFF_T PTRDIFF_T -#endif /* !defined(UPTRDIFF_T) */ - -/* - * We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7). - * However, we'll simply use size_t and convert it to a signed type if - * necessary. This should work just fine in practice. - */ -#ifndef SSIZE_T -#define SSIZE_T size_t -#endif /* !defined(SSIZE_T) */ - -/* Either ERANGE or E2BIG should be available everywhere. */ -#ifndef ERANGE -#define ERANGE E2BIG -#endif /* !defined(ERANGE) */ -#ifndef EOVERFLOW -#define EOVERFLOW ERANGE -#endif /* !defined(EOVERFLOW) */ - -/* - * Buffer size to hold the octal string representation of UINT128_MAX without - * nul-termination ("3777777777777777777777777777777777777777777"). - */ -#ifdef MAX_CONVERT_LENGTH -#undef MAX_CONVERT_LENGTH -#endif /* defined(MAX_CONVERT_LENGTH) */ -#define MAX_CONVERT_LENGTH 43 - -/* Format read states. */ -#define PRINT_S_DEFAULT 0 -#define PRINT_S_FLAGS 1 -#define PRINT_S_WIDTH 2 -#define PRINT_S_DOT 3 -#define PRINT_S_PRECISION 4 -#define PRINT_S_MOD 5 -#define PRINT_S_CONV 6 - -/* Format flags. */ -#define PRINT_F_MINUS (1 << 0) -#define PRINT_F_PLUS (1 << 1) -#define PRINT_F_SPACE (1 << 2) -#define PRINT_F_NUM (1 << 3) -#define PRINT_F_ZERO (1 << 4) -#define PRINT_F_QUOTE (1 << 5) -#define PRINT_F_UP (1 << 6) -#define PRINT_F_UNSIGNED (1 << 7) -#define PRINT_F_TYPE_G (1 << 8) -#define PRINT_F_TYPE_E (1 << 9) - -/* Conversion flags. */ -#define PRINT_C_CHAR 1 -#define PRINT_C_SHORT 2 -#define PRINT_C_LONG 3 -#define PRINT_C_LLONG 4 -#define PRINT_C_LDOUBLE 5 -#define PRINT_C_SIZE 6 -#define PRINT_C_PTRDIFF 7 -#define PRINT_C_INTMAX 8 - -#ifndef MAX -#define MAX(x, y) ((x >= y) ? x : y) -#endif /* !defined(MAX) */ -#ifndef CHARTOINT -#define CHARTOINT(ch) (ch - '0') -#endif /* !defined(CHARTOINT) */ -#ifndef ISDIGIT -#define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9') -#endif /* !defined(ISDIGIT) */ -#ifndef ISNAN -#define ISNAN(x) (x != x) -#endif /* !defined(ISNAN) */ -#ifndef ISINF -#define ISINF(x) (x != 0.0 && x + x == x) -#endif /* !defined(ISINF) */ - -#ifdef OUTCHAR -#undef OUTCHAR -#endif /* defined(OUTCHAR) */ -#define OUTCHAR(str, len, size, ch) \ -do { \ - if (len + 1 < size) \ - str[len] = ch; \ - (len)++; \ -} while (/* CONSTCOND */ 0) - -static void fmtstr(char *, size_t *, size_t, const char *, int, int, int); -static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int); -static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *); -static void printsep(char *, size_t *, size_t); -static int getnumsep(int); -static int getexponent(LDOUBLE); -static int convert(UINTMAX_T, char *, size_t, int, int); -static UINTMAX_T cast(LDOUBLE); -static UINTMAX_T myround(LDOUBLE); -static LDOUBLE mypow10(int); - -/*extern int errno;*/ - -int -rpl_vsnprintf(char *str, size_t size, const char *format, va_list args) -{ - LDOUBLE fvalue; - INTMAX_T value; - unsigned char cvalue; - const char *strvalue; - INTMAX_T *intmaxptr; - PTRDIFF_T *ptrdiffptr; - SSIZE_T *sizeptr; - LLONG *llongptr; - long int *longptr; - int *intptr; - short int *shortptr; - signed char *charptr; - size_t len = 0; - int overflow = 0; - int base = 0; - int cflags = 0; - int flags = 0; - int width = 0; - int precision = -1; - int state = PRINT_S_DEFAULT; - char ch = *format++; - - /* - * C99 says: "If `n' is zero, nothing is written, and `s' may be a null - * pointer." (7.19.6.5, 2) We're forgiving and allow a NULL pointer - * even if a size larger than zero was specified. At least NetBSD's - * snprintf(3) does the same, as well as other versions of this file. - * (Though some of these versions will write to a non-NULL buffer even - * if a size of zero was specified, which violates the standard.) - */ - if (str == NULL && size != 0) - size = 0; - - while (ch != '\0') - switch (state) { - case PRINT_S_DEFAULT: - if (ch == '%') - state = PRINT_S_FLAGS; - else - OUTCHAR(str, len, size, ch); - ch = *format++; - break; - case PRINT_S_FLAGS: - switch (ch) { - case '-': - flags |= PRINT_F_MINUS; - ch = *format++; - break; - case '+': - flags |= PRINT_F_PLUS; - ch = *format++; - break; - case ' ': - flags |= PRINT_F_SPACE; - ch = *format++; - break; - case '#': - flags |= PRINT_F_NUM; - ch = *format++; - break; - case '0': - flags |= PRINT_F_ZERO; - ch = *format++; - break; - case '\'': /* SUSv2 flag (not in C99). */ - flags |= PRINT_F_QUOTE; - ch = *format++; - break; - default: - state = PRINT_S_WIDTH; - break; - } - break; - case PRINT_S_WIDTH: - if (ISDIGIT(ch)) { - ch = CHARTOINT(ch); - if (width > (INT_MAX - ch) / 10) { - overflow = 1; - goto out; - } - width = 10 * width + ch; - ch = *format++; - } else if (ch == '*') { - /* - * C99 says: "A negative field width argument is - * taken as a `-' flag followed by a positive - * field width." (7.19.6.1, 5) - */ - if ((width = va_arg(args, int)) < 0) { - flags |= PRINT_F_MINUS; - width = -width; - } - ch = *format++; - state = PRINT_S_DOT; - } else - state = PRINT_S_DOT; - break; - case PRINT_S_DOT: - if (ch == '.') { - state = PRINT_S_PRECISION; - ch = *format++; - } else - state = PRINT_S_MOD; - break; - case PRINT_S_PRECISION: - if (precision == -1) - precision = 0; - if (ISDIGIT(ch)) { - ch = CHARTOINT(ch); - if (precision > (INT_MAX - ch) / 10) { - overflow = 1; - goto out; - } - precision = 10 * precision + ch; - ch = *format++; - } else if (ch == '*') { - /* - * C99 says: "A negative precision argument is - * taken as if the precision were omitted." - * (7.19.6.1, 5) - */ - if ((precision = va_arg(args, int)) < 0) - precision = -1; - ch = *format++; - state = PRINT_S_MOD; - } else - state = PRINT_S_MOD; - break; - case PRINT_S_MOD: - switch (ch) { - case 'h': - ch = *format++; - if (ch == 'h') { /* It's a char. */ - ch = *format++; - cflags = PRINT_C_CHAR; - } else - cflags = PRINT_C_SHORT; - break; - case 'l': - ch = *format++; - if (ch == 'l') { /* It's a long long. */ - ch = *format++; - cflags = PRINT_C_LLONG; - } else - cflags = PRINT_C_LONG; - break; - case 'L': - cflags = PRINT_C_LDOUBLE; - ch = *format++; - break; - case 'j': - cflags = PRINT_C_INTMAX; - ch = *format++; - break; - case 't': - cflags = PRINT_C_PTRDIFF; - ch = *format++; - break; - case 'z': - cflags = PRINT_C_SIZE; - ch = *format++; - break; - } - state = PRINT_S_CONV; - break; - case PRINT_S_CONV: - switch (ch) { - case 'd': - /* FALLTHROUGH */ - case 'i': - switch (cflags) { - case PRINT_C_CHAR: - value = (signed char)va_arg(args, int); - break; - case PRINT_C_SHORT: - value = (short int)va_arg(args, int); - break; - case PRINT_C_LONG: - value = va_arg(args, long int); - break; - case PRINT_C_LLONG: - value = va_arg(args, LLONG); - break; - case PRINT_C_SIZE: - value = va_arg(args, SSIZE_T); - break; - case PRINT_C_INTMAX: - value = va_arg(args, INTMAX_T); - break; - case PRINT_C_PTRDIFF: - value = va_arg(args, PTRDIFF_T); - break; - default: - value = va_arg(args, int); - break; - } - fmtint(str, &len, size, value, 10, width, - precision, flags); - break; - case 'X': - flags |= PRINT_F_UP; - /* FALLTHROUGH */ - case 'x': - base = 16; - /* FALLTHROUGH */ - case 'o': - if (base == 0) - base = 8; - /* FALLTHROUGH */ - case 'u': - if (base == 0) - base = 10; - flags |= PRINT_F_UNSIGNED; - switch (cflags) { - case PRINT_C_CHAR: - value = (unsigned char)va_arg(args, - unsigned int); - break; - case PRINT_C_SHORT: - value = (unsigned short int)va_arg(args, - unsigned int); - break; - case PRINT_C_LONG: - value = va_arg(args, unsigned long int); - break; - case PRINT_C_LLONG: - value = va_arg(args, ULLONG); - break; - case PRINT_C_SIZE: - value = va_arg(args, size_t); - break; - case PRINT_C_INTMAX: - value = va_arg(args, UINTMAX_T); - break; - case PRINT_C_PTRDIFF: - value = va_arg(args, UPTRDIFF_T); - break; - default: - value = va_arg(args, unsigned int); - break; - } - fmtint(str, &len, size, value, base, width, - precision, flags); - break; - case 'A': - /* Not yet supported, we'll use "%F". */ - /* FALLTHROUGH */ - case 'F': - flags |= PRINT_F_UP; - case 'a': - /* Not yet supported, we'll use "%f". */ - /* FALLTHROUGH */ - case 'f': - if (cflags == PRINT_C_LDOUBLE) - fvalue = va_arg(args, LDOUBLE); - else - fvalue = va_arg(args, double); - fmtflt(str, &len, size, fvalue, width, - precision, flags, &overflow); - if (overflow) - goto out; - break; - case 'E': - flags |= PRINT_F_UP; - /* FALLTHROUGH */ - case 'e': - flags |= PRINT_F_TYPE_E; - if (cflags == PRINT_C_LDOUBLE) - fvalue = va_arg(args, LDOUBLE); - else - fvalue = va_arg(args, double); - fmtflt(str, &len, size, fvalue, width, - precision, flags, &overflow); - if (overflow) - goto out; - break; - case 'G': - flags |= PRINT_F_UP; - /* FALLTHROUGH */ - case 'g': - flags |= PRINT_F_TYPE_G; - if (cflags == PRINT_C_LDOUBLE) - fvalue = va_arg(args, LDOUBLE); - else - fvalue = va_arg(args, double); - /* - * If the precision is zero, it is treated as - * one (cf. C99: 7.19.6.1, 8). - */ - if (precision == 0) - precision = 1; - fmtflt(str, &len, size, fvalue, width, - precision, flags, &overflow); - if (overflow) - goto out; - break; - case 'c': - cvalue = va_arg(args, int); - OUTCHAR(str, len, size, cvalue); - break; - case 's': - strvalue = va_arg(args, char *); - fmtstr(str, &len, size, strvalue, width, - precision, flags); - break; - case 'p': - /* - * C99 says: "The value of the pointer is - * converted to a sequence of printing - * characters, in an implementation-defined - * manner." (C99: 7.19.6.1, 8) - */ - if ((strvalue = (const char*)va_arg(args, void *)) == NULL) - /* - * We use the glibc format. BSD prints - * "0x0", SysV "0". - */ - fmtstr(str, &len, size, "(nil)", width, - -1, flags); - else { - /* - * We use the BSD/glibc format. SysV - * omits the "0x" prefix (which we emit - * using the PRINT_F_NUM flag). - */ - flags |= PRINT_F_NUM; - flags |= PRINT_F_UNSIGNED; - fmtint(str, &len, size, - (UINTPTR_T)strvalue, 16, width, - precision, flags); - } - break; - case 'n': - switch (cflags) { - case PRINT_C_CHAR: - charptr = va_arg(args, signed char *); - *charptr = len; - break; - case PRINT_C_SHORT: - shortptr = va_arg(args, short int *); - *shortptr = len; - break; - case PRINT_C_LONG: - longptr = va_arg(args, long int *); - *longptr = len; - break; - case PRINT_C_LLONG: - llongptr = va_arg(args, LLONG *); - *llongptr = len; - break; - case PRINT_C_SIZE: - /* - * C99 says that with the "z" length - * modifier, "a following `n' conversion - * specifier applies to a pointer to a - * signed integer type corresponding to - * size_t argument." (7.19.6.1, 7) - */ - sizeptr = va_arg(args, SSIZE_T *); - *sizeptr = len; - break; - case PRINT_C_INTMAX: - intmaxptr = va_arg(args, INTMAX_T *); - *intmaxptr = len; - break; - case PRINT_C_PTRDIFF: - ptrdiffptr = va_arg(args, PTRDIFF_T *); - *ptrdiffptr = len; - break; - default: - intptr = va_arg(args, int *); - *intptr = len; - break; - } - break; - case '%': /* Print a "%" character verbatim. */ - OUTCHAR(str, len, size, ch); - break; - default: /* Skip other characters. */ - break; - } - ch = *format++; - state = PRINT_S_DEFAULT; - base = cflags = flags = width = 0; - precision = -1; - break; - } -out: - if (len < size) - str[len] = '\0'; - else if (size > 0) - str[size - 1] = '\0'; - - if (overflow || len >= INT_MAX) { - errno = overflow ? EOVERFLOW : ERANGE; - return -1; - } - return (int)len; -} - -static void -fmtstr(char *str, size_t *len, size_t size, const char *value, int width, - int precision, int flags) -{ - int padlen, strln; /* Amount to pad. */ - int noprecision = (precision == -1); - - if (value == NULL) /* We're forgiving. */ - value = "(null)"; - - /* If a precision was specified, don't read the string past it. */ - for (strln = 0; value[strln] != '\0' && - (noprecision || strln < precision); strln++) - continue; - - if ((padlen = width - strln) < 0) - padlen = 0; - if (flags & PRINT_F_MINUS) /* Left justify. */ - padlen = -padlen; - - while (padlen > 0) { /* Leading spaces. */ - OUTCHAR(str, *len, size, ' '); - padlen--; - } - while (*value != '\0' && (noprecision || precision-- > 0)) { - OUTCHAR(str, *len, size, *value); - value++; - } - while (padlen < 0) { /* Trailing spaces. */ - OUTCHAR(str, *len, size, ' '); - padlen++; - } -} - -static void -fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width, - int precision, int flags) -{ - UINTMAX_T uvalue; - char iconvert[MAX_CONVERT_LENGTH]; - char sign = 0; - char hexprefix = 0; - int spadlen = 0; /* Amount to space pad. */ - int zpadlen = 0; /* Amount to zero pad. */ - int pos; - int separators = (flags & PRINT_F_QUOTE); - int noprecision = (precision == -1); - - if (flags & PRINT_F_UNSIGNED) - uvalue = value; - else { - uvalue = (value >= 0) ? value : -value; - if (value < 0) - sign = '-'; - else if (flags & PRINT_F_PLUS) /* Do a sign. */ - sign = '+'; - else if (flags & PRINT_F_SPACE) - sign = ' '; - } - - pos = convert(uvalue, iconvert, sizeof(iconvert), base, - flags & PRINT_F_UP); - - if (flags & PRINT_F_NUM && uvalue != 0) { - /* - * C99 says: "The result is converted to an `alternative form'. - * For `o' conversion, it increases the precision, if and only - * if necessary, to force the first digit of the result to be a - * zero (if the value and precision are both 0, a single 0 is - * printed). For `x' (or `X') conversion, a nonzero result has - * `0x' (or `0X') prefixed to it." (7.19.6.1, 6) - */ - switch (base) { - case 8: - if (precision <= pos) - precision = pos + 1; - break; - case 16: - hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x'; - break; - } - } - - if (separators) /* Get the number of group separators we'll print. */ - separators = getnumsep(pos); - - zpadlen = precision - pos - separators; - spadlen = width /* Minimum field width. */ - - separators /* Number of separators. */ - - MAX(precision, pos) /* Number of integer digits. */ - - ((sign != 0) ? 1 : 0) /* Will we print a sign? */ - - ((hexprefix != 0) ? 2 : 0); /* Will we print a prefix? */ - - if (zpadlen < 0) - zpadlen = 0; - if (spadlen < 0) - spadlen = 0; - - /* - * C99 says: "If the `0' and `-' flags both appear, the `0' flag is - * ignored. For `d', `i', `o', `u', `x', and `X' conversions, if a - * precision is specified, the `0' flag is ignored." (7.19.6.1, 6) - */ - if (flags & PRINT_F_MINUS) /* Left justify. */ - spadlen = -spadlen; - else if (flags & PRINT_F_ZERO && noprecision) { - zpadlen += spadlen; - spadlen = 0; - } - while (spadlen > 0) { /* Leading spaces. */ - OUTCHAR(str, *len, size, ' '); - spadlen--; - } - if (sign != 0) /* Sign. */ - OUTCHAR(str, *len, size, sign); - if (hexprefix != 0) { /* A "0x" or "0X" prefix. */ - OUTCHAR(str, *len, size, '0'); - OUTCHAR(str, *len, size, hexprefix); - } - while (zpadlen > 0) { /* Leading zeros. */ - OUTCHAR(str, *len, size, '0'); - zpadlen--; - } - while (pos > 0) { /* The actual digits. */ - pos--; - OUTCHAR(str, *len, size, iconvert[pos]); - if (separators > 0 && pos > 0 && pos % 3 == 0) - printsep(str, len, size); - } - while (spadlen < 0) { /* Trailing spaces. */ - OUTCHAR(str, *len, size, ' '); - spadlen++; - } -} - -static void -fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width, - int precision, int flags, int *overflow) -{ - LDOUBLE ufvalue; - UINTMAX_T intpart; - UINTMAX_T fracpart; - UINTMAX_T mask; - const char *infnan = NULL; - char iconvert[MAX_CONVERT_LENGTH]; - char fconvert[MAX_CONVERT_LENGTH]; - char econvert[4]; /* "e-12" (without nul-termination). */ - char esign = 0; - char sign = 0; - int leadfraczeros = 0; - int exponent = 0; - int emitpoint = 0; - int omitzeros = 0; - int omitcount = 0; - int padlen = 0; - int epos = 0; - int fpos = 0; - int ipos = 0; - int separators = (flags & PRINT_F_QUOTE); - int estyle = (flags & PRINT_F_TYPE_E); -#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT - struct lconv *lc = localeconv(); -#endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ - - /* - * AIX' man page says the default is 0, but C99 and at least Solaris' - * and NetBSD's man pages say the default is 6, and sprintf(3) on AIX - * defaults to 6. - */ - if (precision == -1) - precision = 6; - - if (fvalue < 0.0) - sign = '-'; - else if (flags & PRINT_F_PLUS) /* Do a sign. */ - sign = '+'; - else if (flags & PRINT_F_SPACE) - sign = ' '; - - if (ISNAN(fvalue)) - infnan = (flags & PRINT_F_UP) ? "NAN" : "nan"; - else if (ISINF(fvalue)) - infnan = (flags & PRINT_F_UP) ? "INF" : "inf"; - - if (infnan != NULL) { - if (sign != 0) - iconvert[ipos++] = sign; - while (*infnan != '\0') - iconvert[ipos++] = *infnan++; - fmtstr(str, len, size, iconvert, width, ipos, flags); - return; - } - - /* "%e" (or "%E") or "%g" (or "%G") conversion. */ - if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) { - if (flags & PRINT_F_TYPE_G) { - /* - * For "%g" (and "%G") conversions, the precision - * specifies the number of significant digits, which - * includes the digits in the integer part. The - * conversion will or will not be using "e-style" (like - * "%e" or "%E" conversions) depending on the precision - * and on the exponent. However, the exponent can be - * affected by rounding the converted value, so we'll - * leave this decision for later. Until then, we'll - * assume that we're going to do an "e-style" conversion - * (in order to get the exponent calculated). For - * "e-style", the precision must be decremented by one. - */ - precision--; - /* - * For "%g" (and "%G") conversions, trailing zeros are - * removed from the fractional portion of the result - * unless the "#" flag was specified. - */ - if (!(flags & PRINT_F_NUM)) - omitzeros = 1; - } - exponent = getexponent(fvalue); - estyle = 1; - } - -again: - /* - * Sorry, we only support 9, 19, or 38 digits (that is, the number of - * digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value - * minus one) past the decimal point due to our conversion method. - */ - switch (sizeof(UINTMAX_T)) { - case 16: - if (precision > 38) - precision = 38; - break; - case 8: - if (precision > 19) - precision = 19; - break; - default: - if (precision > 9) - precision = 9; - break; - } - - ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue; - if (estyle) /* We want exactly one integer digit. */ - ufvalue /= mypow10(exponent); - - if ((intpart = cast(ufvalue)) == UINTMAX_MAX) { - *overflow = 1; - return; - } - - /* - * Factor of ten with the number of digits needed for the fractional - * part. For example, if the precision is 3, the mask will be 1000. - */ - mask = mypow10(precision); - /* - * We "cheat" by converting the fractional part to integer by - * multiplying by a factor of ten. - */ - if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) { - /* - * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000 - * (because precision = 3). Now, myround(1000 * 0.99962) will - * return 1000. So, the integer part must be incremented by one - * and the fractional part must be set to zero. - */ - intpart++; - fracpart = 0; - if (estyle && intpart == 10) { - /* - * The value was rounded up to ten, but we only want one - * integer digit if using "e-style". So, the integer - * part must be set to one and the exponent must be - * incremented by one. - */ - intpart = 1; - exponent++; - } - } - - /* - * Now that we know the real exponent, we can check whether or not to - * use "e-style" for "%g" (and "%G") conversions. If we don't need - * "e-style", the precision must be adjusted and the integer and - * fractional parts must be recalculated from the original value. - * - * C99 says: "Let P equal the precision if nonzero, 6 if the precision - * is omitted, or 1 if the precision is zero. Then, if a conversion - * with style `E' would have an exponent of X: - * - * - if P > X >= -4, the conversion is with style `f' (or `F') and - * precision P - (X + 1). - * - * - otherwise, the conversion is with style `e' (or `E') and precision - * P - 1." (7.19.6.1, 8) - * - * Note that we had decremented the precision by one. - */ - if (flags & PRINT_F_TYPE_G && estyle && - precision + 1 > exponent && exponent >= -4) { - precision -= exponent; - estyle = 0; - goto again; - } - - if (estyle) { - if (exponent < 0) { - exponent = -exponent; - esign = '-'; - } else - esign = '+'; - - /* - * Convert the exponent. The sizeof(econvert) is 4. So, the - * econvert buffer can hold e.g. "e+99" and "e-99". We don't - * support an exponent which contains more than two digits. - * Therefore, the following stores are safe. - */ - epos = convert(exponent, econvert, 2, 10, 0); - /* - * C99 says: "The exponent always contains at least two digits, - * and only as many more digits as necessary to represent the - * exponent." (7.19.6.1, 8) - */ - if (epos == 1) - econvert[epos++] = '0'; - econvert[epos++] = esign; - econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e'; - } - - /* Convert the integer part and the fractional part. */ - ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0); - if (fracpart != 0) /* convert() would return 1 if fracpart == 0. */ - fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0); - - leadfraczeros = precision - fpos; - - if (omitzeros) { - if (fpos > 0) /* Omit trailing fractional part zeros. */ - while (omitcount < fpos && fconvert[omitcount] == '0') - omitcount++; - else { /* The fractional part is zero, omit it completely. */ - omitcount = precision; - leadfraczeros = 0; - } - precision -= omitcount; - } - - /* - * Print a decimal point if either the fractional part is non-zero - * and/or the "#" flag was specified. - */ - if (precision > 0 || flags & PRINT_F_NUM) - emitpoint = 1; - if (separators) /* Get the number of group separators we'll print. */ - separators = getnumsep(ipos); - - padlen = width /* Minimum field width. */ - - ipos /* Number of integer digits. */ - - epos /* Number of exponent characters. */ - - precision /* Number of fractional digits. */ - - separators /* Number of group separators. */ - - (emitpoint ? 1 : 0) /* Will we print a decimal point? */ - - ((sign != 0) ? 1 : 0); /* Will we print a sign character? */ - - if (padlen < 0) - padlen = 0; - - /* - * C99 says: "If the `0' and `-' flags both appear, the `0' flag is - * ignored." (7.19.6.1, 6) - */ - if (flags & PRINT_F_MINUS) /* Left justifty. */ - padlen = -padlen; - else if (flags & PRINT_F_ZERO && padlen > 0) { - if (sign != 0) { /* Sign. */ - OUTCHAR(str, *len, size, sign); - sign = 0; - } - while (padlen > 0) { /* Leading zeros. */ - OUTCHAR(str, *len, size, '0'); - padlen--; - } - } - while (padlen > 0) { /* Leading spaces. */ - OUTCHAR(str, *len, size, ' '); - padlen--; - } - if (sign != 0) /* Sign. */ - OUTCHAR(str, *len, size, sign); - while (ipos > 0) { /* Integer part. */ - ipos--; - OUTCHAR(str, *len, size, iconvert[ipos]); - if (separators > 0 && ipos > 0 && ipos % 3 == 0) - printsep(str, len, size); - } - if (emitpoint) { /* Decimal point. */ -#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT - if (lc->decimal_point != NULL && *lc->decimal_point != '\0') - OUTCHAR(str, *len, size, *lc->decimal_point); - else /* We'll always print some decimal point character. */ -#endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ - OUTCHAR(str, *len, size, '.'); - } - while (leadfraczeros > 0) { /* Leading fractional part zeros. */ - OUTCHAR(str, *len, size, '0'); - leadfraczeros--; - } - while (fpos > omitcount) { /* The remaining fractional part. */ - fpos--; - OUTCHAR(str, *len, size, fconvert[fpos]); - } - while (epos > 0) { /* Exponent. */ - epos--; - OUTCHAR(str, *len, size, econvert[epos]); - } - while (padlen < 0) { /* Trailing spaces. */ - OUTCHAR(str, *len, size, ' '); - padlen++; - } -} - -static void -printsep(char *str, size_t *len, size_t size) -{ -#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP - struct lconv *lc = localeconv(); - int i; - - if (lc->thousands_sep != NULL) - for (i = 0; lc->thousands_sep[i] != '\0'; i++) - OUTCHAR(str, *len, size, lc->thousands_sep[i]); - else -#endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ - OUTCHAR(str, *len, size, ','); -} - -static int -getnumsep(int digits) -{ - int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3; -#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP - int strln; - struct lconv *lc = localeconv(); - - /* We support an arbitrary separator length (including zero). */ - if (lc->thousands_sep != NULL) { - for (strln = 0; lc->thousands_sep[strln] != '\0'; strln++) - continue; - separators *= strln; - } -#endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ - return separators; -} - -static int -getexponent(LDOUBLE value) -{ - LDOUBLE tmp = (value >= 0.0) ? value : -value; - int exponent = 0; - - /* - * We check for 99 > exponent > -99 in order to work around possible - * endless loops which could happen (at least) in the second loop (at - * least) if we're called with an infinite value. However, we checked - * for infinity before calling this function using our ISINF() macro, so - * this might be somewhat paranoid. - */ - while (tmp < 1.0 && tmp > 0.0 && --exponent > -99) - tmp *= 10; - while (tmp >= 10.0 && ++exponent < 99) - tmp /= 10; - - return exponent; -} - -static int -convert(UINTMAX_T value, char *buf, size_t size, int base, int caps) -{ - const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef"; - size_t pos = 0; - - /* We return an unterminated buffer with the digits in reverse order. */ - do { - buf[pos++] = digits[value % base]; - value /= base; - } while (value != 0 && pos < size); - - return (int)pos; -} - -static UINTMAX_T -cast(LDOUBLE value) -{ - UINTMAX_T result; - - /* - * We check for ">=" and not for ">" because if UINTMAX_MAX cannot be - * represented exactly as an LDOUBLE value (but is less than LDBL_MAX), - * it may be increased to the nearest higher representable value for the - * comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE - * value although converting the latter to UINTMAX_T would overflow. - */ - if (value >= UINTMAX_MAX) - return UINTMAX_MAX; - - result = value; - /* - * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to - * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates - * the standard). Sigh. - */ - return (result <= value) ? result : result - 1; -} - -static UINTMAX_T -myround(LDOUBLE value) -{ - UINTMAX_T intpart = cast(value); - - return ((value -= intpart) < 0.5) ? intpart : intpart + 1; -} - -static LDOUBLE -mypow10(int exponent) -{ - LDOUBLE result = 1; - - while (exponent > 0) { - result *= 10; - exponent--; - } - while (exponent < 0) { - result /= 10; - exponent++; - } - return result; -} -#endif /* !HAVE_VSNPRINTF */ - -#if !HAVE_VASPRINTF -#if NEED_MYMEMCPY -static void * -mymemcpy(void *dst, void *src, size_t len) -{ - const char *from = (const char *)src; - char *to = (char*)dst; - - /* No need for optimization, we use this only to replace va_copy(3). */ - while (len-- > 0) - *to++ = *from++; - return dst; -} -#endif /* NEED_MYMEMCPY */ - -int -rpl_vasprintf(char **ret, const char *format, va_list ap) -{ - size_t size; - int len; - va_list aq; - - VA_COPY(aq, ap); -#if !HAVE_VSNPRINTF - len = rpl_vsnprintf(NULL, 0, format, aq); -#else - len = vsnprintf(NULL, 0, format, aq); -#endif - VA_END_COPY(aq); - if (len < 0 || (*ret = (char*)malloc(size = len + 1)) == NULL) - return -1; -#if !HAVE_VSNPRINTF - return rpl_vsnprintf(*ret, size, format, ap); -#else - return vsnprintf(*ret, size, format, ap); -#endif -} -#endif /* !HAVE_VASPRINTF */ - -#if !HAVE_SNPRINTF -#if HAVE_STDARG_H -int -rpl_snprintf(char *str, size_t size, const char *format, ...) -#else -int -rpl_snprintf(va_alist) va_dcl -#endif /* HAVE_STDARG_H */ -{ -#if !HAVE_STDARG_H - char *str; - size_t size; - char *format; -#endif /* HAVE_STDARG_H */ - va_list ap; - int len; - - VA_START(ap, format); - VA_SHIFT(ap, str, char *); - VA_SHIFT(ap, size, size_t); - VA_SHIFT(ap, format, const char *); -#if !HAVE_VSNPRINTF - len = rpl_vsnprintf(str, size, format, ap); -#else - len = vsnprintf(str, size, format, ap); -#endif - va_end(ap); - return len; -} -#endif /* !HAVE_SNPRINTF */ - -#if !HAVE_ASPRINTF -#if HAVE_STDARG_H -int -rpl_asprintf(char **ret, const char *format, ...) -#else -int -rpl_asprintf(va_alist) va_dcl -#endif /* HAVE_STDARG_H */ -{ -#if !HAVE_STDARG_H - char **ret; - char *format; -#endif /* HAVE_STDARG_H */ - va_list ap; - int len; - - VA_START(ap, format); - VA_SHIFT(ap, ret, char **); - VA_SHIFT(ap, format, const char *); -#if !HAVE_VASPRINTF - len = rpl_vasprintf(ret, format, ap); -#else - len = vasprintf(ret, format, ap); -#endif - va_end(ap); - return len; -} -#endif /* !HAVE_ASPRINTF */ -#else /* Dummy declaration to avoid empty translation unit warnings. */ -int main(int argc, char **argv); -#endif /* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */ diff --git a/ModelicaExternalC/C-Sources/stdint_msvc.h b/ModelicaExternalC/C-Sources/stdint_msvc.h deleted file mode 100644 index cb2acd938..000000000 --- a/ModelicaExternalC/C-Sources/stdint_msvc.h +++ /dev/null @@ -1,259 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2013 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the product nor the names of its contributors may -// be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#if _MSC_VER >= 1600 // [ -#include -#else // ] _MSC_VER >= 1600 [ - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -// These #ifndef's are needed to prevent collisions with . -// Check out Issue 9 for the details. -#ifndef INTMAX_C // [ -# define INTMAX_C INT64_C -#endif // INTMAX_C ] -#ifndef UINTMAX_C // [ -# define UINTMAX_C UINT64_C -#endif // UINTMAX_C ] - -#endif // __STDC_CONSTANT_MACROS ] - -#endif // _MSC_VER >= 1600 ] - -#endif // _MSC_STDINT_H_ ] diff --git a/ModelicaExternalC/C-Sources/stdint_wrap.h b/ModelicaExternalC/C-Sources/stdint_wrap.h deleted file mode 100644 index 3e3e67068..000000000 --- a/ModelicaExternalC/C-Sources/stdint_wrap.h +++ /dev/null @@ -1,98 +0,0 @@ -/* stdint_wrap.h - Wrapper for stdint.h not being available with C89 - - Copyright (C) 2020, Modelica Association and contributors - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef MODELICA_STDINT_WRAP_H_ -#define MODELICA_STDINT_WRAP_H_ - -/* Have 64 bit integral types */ -#if defined(_WIN32) -#if defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) || defined(__BORLANDC__) -#define HAVE_MODELICA_INT64_T 1 -#define HAVE_MODELICA_UINT64_T 1 -#elif defined(_MSC_VER) && _MSC_VER > 1300 -#define HAVE_MODELICA_INT64_T 1 -#define HAVE_MODELICA_UINT64_T 1 -#elif defined(_MSC_VER) -#define HAVE_MODELICA_INT64_T 1 -#undef HAVE_MODELICA_UINT64_T -#else -#undef HAVE_MODELICA_INT64_T -#undef HAVE_MODELICA_UINT64_T -#endif -#else -#define HAVE_MODELICA_INT64_T 1 -#define HAVE_MODELICA_UINT64_T 1 -#endif - -/* Have the header file */ -#if defined(_WIN32) -#if defined(_MSC_VER) && _MSC_VER >= 1600 -#define HAVE_MODELICA_STDINT_H 1 -#elif defined(__WATCOMC__) || defined(__MINGW32__) || defined(__CYGWIN__) -#define HAVE_MODELICA_STDINT_H 1 -#else -#undef HAVE_MODELICA_STDINT_H -#endif -#elif defined(__GNUC__) && !defined(__VXWORKS__) -#define HAVE_MODELICA_STDINT_H 1 -#else -#undef HAVE_MODELICA_STDINT_H -#endif - -/* Include integer type header */ -#if defined(HAVE_MODELICA_STDINT_H) -#include -#elif defined(_MSC_VER) -#include "stdint_msvc.h" -#else -#define int8_t signed char -#define uint8_t unsigned char -#define int16_t short -#define uint16_t unsigned short -#define int32_t int -#define uint32_t unsigned int -#if defined(HAVE_MODELICA_INT64_T) -#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300) -#define int64_t __int64 -#else -#define int64_t long long -#endif -#endif -#if defined(HAVE_MODELICA_UINT64_T) -#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER < 1300) -#define uint64_t unsigned __int64 -#else -#define uint64_t unsigned long long -#endif -#endif -#endif - -#endif diff --git a/ModelicaExternalC/C-Sources/uthash.h b/ModelicaExternalC/C-Sources/uthash.h deleted file mode 100644 index ac78fdab5..000000000 --- a/ModelicaExternalC/C-Sources/uthash.h +++ /dev/null @@ -1,1136 +0,0 @@ -/* -Copyright (c) 2003-2021, Troy D. Hanson http://troydhanson.github.com/uthash/ -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef UTHASH_H -#define UTHASH_H - -#define UTHASH_VERSION 2.3.0 - -#include /* memcmp, memset, strlen */ -#include /* ptrdiff_t */ -#include /* exit */ - -#if defined(HASH_DEFINE_OWN_STDINT) && HASH_DEFINE_OWN_STDINT -/* This codepath is provided for backward compatibility, but I plan to remove it. */ -#warning "HASH_DEFINE_OWN_STDINT is deprecated; please use HASH_NO_STDINT instead" -typedef unsigned int uint32_t; -typedef unsigned char uint8_t; -#elif defined(HASH_NO_STDINT) && HASH_NO_STDINT -#else -#include /* uint8_t, uint32_t */ -#endif - -/* These macros use decltype or the earlier __typeof GNU extension. - As decltype is only available in newer compilers (VS2010 or gcc 4.3+ - when compiling c++ source) this code uses whatever method is needed - or, for VS2008 where neither is available, uses casting workarounds. */ -#if !defined(DECLTYPE) && !defined(NO_DECLTYPE) -#if defined(_MSC_VER) /* MS compiler */ -#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ -#define DECLTYPE(x) (decltype(x)) -#else /* VS2008 or older (or VS2010 in C mode) */ -#define NO_DECLTYPE -#endif -#elif defined(__BORLANDC__) || defined(__ICCARM__) || defined(__LCC__) || defined(__WATCOMC__) -#define NO_DECLTYPE -#else /* GNU, Sun and other compilers */ -#define DECLTYPE(x) (__typeof(x)) -#endif -#endif - -#ifdef NO_DECLTYPE -#define DECLTYPE(x) -#define DECLTYPE_ASSIGN(dst,src) \ -do { \ - char **_da_dst = (char**)(&(dst)); \ - *_da_dst = (char*)(src); \ -} while (0) -#else -#define DECLTYPE_ASSIGN(dst,src) \ -do { \ - (dst) = DECLTYPE(dst)(src); \ -} while (0) -#endif - -#ifndef uthash_malloc -#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ -#endif -#ifndef uthash_free -#define uthash_free(ptr,sz) free(ptr) /* free fcn */ -#endif -#ifndef uthash_bzero -#define uthash_bzero(a,n) memset(a,'\0',n) -#endif -#ifndef uthash_strlen -#define uthash_strlen(s) strlen(s) -#endif - -#ifndef HASH_FUNCTION -#define HASH_FUNCTION(keyptr,keylen,hashv) HASH_JEN(keyptr, keylen, hashv) -#endif - -#ifndef HASH_KEYCMP -#define HASH_KEYCMP(a,b,n) memcmp(a,b,n) -#endif - -#ifndef uthash_noexpand_fyi -#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ -#endif -#ifndef uthash_expand_fyi -#define uthash_expand_fyi(tbl) /* can be defined to log expands */ -#endif - -#ifndef HASH_NONFATAL_OOM -#define HASH_NONFATAL_OOM 0 -#endif - -#if HASH_NONFATAL_OOM -/* malloc failures can be recovered from */ - -#ifndef uthash_nonfatal_oom -#define uthash_nonfatal_oom(obj) do {} while (0) /* non-fatal OOM error */ -#endif - -#define HASH_RECORD_OOM(oomed) do { (oomed) = 1; } while (0) -#define IF_HASH_NONFATAL_OOM(x) x - -#else -/* malloc failures result in lost memory, hash tables are unusable */ - -#ifndef uthash_fatal -#define uthash_fatal(msg) exit(-1) /* fatal OOM error */ -#endif - -#define HASH_RECORD_OOM(oomed) uthash_fatal("out of memory") -#define IF_HASH_NONFATAL_OOM(x) - -#endif - -/* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS 32U /* initial number of buckets */ -#define HASH_INITIAL_NUM_BUCKETS_LOG2 5U /* lg2 of initial number of buckets */ -#define HASH_BKT_CAPACITY_THRESH 10U /* expand when bucket count reaches */ - -/* calculate the element whose hash handle address is hhp */ -#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) -/* calculate the hash handle from element address elp */ -#define HH_FROM_ELMT(tbl,elp) ((UT_hash_handle*)(void*)(((char*)(elp)) + ((tbl)->hho))) - -#define HASH_ROLLBACK_BKT(hh, head, itemptrhh) \ -do { \ - struct UT_hash_handle *_hd_hh_item = (itemptrhh); \ - unsigned _hd_bkt; \ - HASH_TO_BKT(_hd_hh_item->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ - (head)->hh.tbl->buckets[_hd_bkt].count++; \ - _hd_hh_item->hh_next = NULL; \ - _hd_hh_item->hh_prev = NULL; \ -} while (0) - -#define HASH_VALUE(keyptr,keylen,hashv) \ -do { \ - HASH_FUNCTION(keyptr, keylen, hashv); \ -} while (0) - -#define HASH_FIND_BYHASHVALUE(hh,head,keyptr,keylen,hashval,out) \ -do { \ - (out) = NULL; \ - if (head) { \ - unsigned _hf_bkt; \ - HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \ - if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0) { \ - HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \ - } \ - } \ -} while (0) - -#define HASH_FIND(hh,head,keyptr,keylen,out) \ -do { \ - (out) = NULL; \ - if (head) { \ - unsigned _hf_hashv; \ - HASH_VALUE(keyptr, keylen, _hf_hashv); \ - HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \ - } \ -} while (0) - -#ifdef HASH_BLOOM -#define HASH_BLOOM_BITLEN (1UL << HASH_BLOOM) -#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8UL) + (((HASH_BLOOM_BITLEN%8UL)!=0UL) ? 1UL : 0UL) -#define HASH_BLOOM_MAKE(tbl,oomed) \ -do { \ - (tbl)->bloom_nbits = HASH_BLOOM; \ - (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ - if (!(tbl)->bloom_bv) { \ - HASH_RECORD_OOM(oomed); \ - } else { \ - uthash_bzero((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ - (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ - } \ -} while (0) - -#define HASH_BLOOM_FREE(tbl) \ -do { \ - uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ -} while (0) - -#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8U] |= (1U << ((idx)%8U))) -#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8U] & (1U << ((idx)%8U))) - -#define HASH_BLOOM_ADD(tbl,hashv) \ - HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) - -#define HASH_BLOOM_TEST(tbl,hashv) \ - HASH_BLOOM_BITTEST((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U))) - -#else -#define HASH_BLOOM_MAKE(tbl,oomed) -#define HASH_BLOOM_FREE(tbl) -#define HASH_BLOOM_ADD(tbl,hashv) -#define HASH_BLOOM_TEST(tbl,hashv) (1) -#define HASH_BLOOM_BYTELEN 0U -#endif - -#define HASH_MAKE_TABLE(hh,head,oomed) \ -do { \ - (head)->hh.tbl = (UT_hash_table*)uthash_malloc(sizeof(UT_hash_table)); \ - if (!(head)->hh.tbl) { \ - HASH_RECORD_OOM(oomed); \ - } else { \ - uthash_bzero((head)->hh.tbl, sizeof(UT_hash_table)); \ - (head)->hh.tbl->tail = &((head)->hh); \ - (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ - (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ - (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ - (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ - HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ - (head)->hh.tbl->signature = HASH_SIGNATURE; \ - if (!(head)->hh.tbl->buckets) { \ - HASH_RECORD_OOM(oomed); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - } else { \ - uthash_bzero((head)->hh.tbl->buckets, \ - HASH_INITIAL_NUM_BUCKETS * sizeof(struct UT_hash_bucket)); \ - HASH_BLOOM_MAKE((head)->hh.tbl, oomed); \ - IF_HASH_NONFATAL_OOM( \ - if (oomed) { \ - uthash_free((head)->hh.tbl->buckets, \ - HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - } \ - ) \ - } \ - } \ -} while (0) - -#define HASH_REPLACE_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,replaced,cmpfcn) \ -do { \ - (replaced) = NULL; \ - HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ - if (replaced) { \ - HASH_DELETE(hh, head, replaced); \ - } \ - HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn); \ -} while (0) - -#define HASH_REPLACE_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add,replaced) \ -do { \ - (replaced) = NULL; \ - HASH_FIND_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, replaced); \ - if (replaced) { \ - HASH_DELETE(hh, head, replaced); \ - } \ - HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add); \ -} while (0) - -#define HASH_REPLACE(hh,head,fieldname,keylen_in,add,replaced) \ -do { \ - unsigned _hr_hashv; \ - HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ - HASH_REPLACE_BYHASHVALUE(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced); \ -} while (0) - -#define HASH_REPLACE_INORDER(hh,head,fieldname,keylen_in,add,replaced,cmpfcn) \ -do { \ - unsigned _hr_hashv; \ - HASH_VALUE(&((add)->fieldname), keylen_in, _hr_hashv); \ - HASH_REPLACE_BYHASHVALUE_INORDER(hh, head, fieldname, keylen_in, _hr_hashv, add, replaced, cmpfcn); \ -} while (0) - -#define HASH_APPEND_LIST(hh, head, add) \ -do { \ - (add)->hh.next = NULL; \ - (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ - (head)->hh.tbl->tail->next = (add); \ - (head)->hh.tbl->tail = &((add)->hh); \ -} while (0) - -#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ -do { \ - do { \ - if (cmpfcn(DECLTYPE(head)(_hs_iter), add) > 0) { \ - break; \ - } \ - } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ -} while (0) - -#ifdef NO_DECLTYPE -#undef HASH_AKBI_INNER_LOOP -#define HASH_AKBI_INNER_LOOP(hh,head,add,cmpfcn) \ -do { \ - char *_hs_saved_head = (char*)(head); \ - do { \ - DECLTYPE_ASSIGN(head, _hs_iter); \ - if (cmpfcn(head, add) > 0) { \ - DECLTYPE_ASSIGN(head, _hs_saved_head); \ - break; \ - } \ - DECLTYPE_ASSIGN(head, _hs_saved_head); \ - } while ((_hs_iter = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->next)); \ -} while (0) -#endif - -#if HASH_NONFATAL_OOM - -#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ -do { \ - if (!(oomed)) { \ - unsigned _ha_bkt; \ - (head)->hh.tbl->num_items++; \ - HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ - HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ - if (oomed) { \ - HASH_ROLLBACK_BKT(hh, head, &(add)->hh); \ - HASH_DELETE_HH(hh, head, &(add)->hh); \ - (add)->hh.tbl = NULL; \ - uthash_nonfatal_oom(add); \ - } else { \ - HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ - HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ - } \ - } else { \ - (add)->hh.tbl = NULL; \ - uthash_nonfatal_oom(add); \ - } \ -} while (0) - -#else - -#define HASH_ADD_TO_TABLE(hh,head,keyptr,keylen_in,hashval,add,oomed) \ -do { \ - unsigned _ha_bkt; \ - (head)->hh.tbl->num_items++; \ - HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _ha_bkt); \ - HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt], hh, &(add)->hh, oomed); \ - HASH_BLOOM_ADD((head)->hh.tbl, hashval); \ - HASH_EMIT_KEY(hh, head, keyptr, keylen_in); \ -} while (0) - -#endif - - -#define HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh,head,keyptr,keylen_in,hashval,add,cmpfcn) \ -do { \ - IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ - (add)->hh.hashv = (hashval); \ - (add)->hh.key = (char*) (keyptr); \ - (add)->hh.keylen = (unsigned) (keylen_in); \ - if (!(head)) { \ - (add)->hh.next = NULL; \ - (add)->hh.prev = NULL; \ - HASH_MAKE_TABLE(hh, add, _ha_oomed); \ - IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ - (head) = (add); \ - IF_HASH_NONFATAL_OOM( } ) \ - } else { \ - void *_hs_iter = (head); \ - (add)->hh.tbl = (head)->hh.tbl; \ - HASH_AKBI_INNER_LOOP(hh, head, add, cmpfcn); \ - if (_hs_iter) { \ - (add)->hh.next = _hs_iter; \ - if (((add)->hh.prev = HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev)) { \ - HH_FROM_ELMT((head)->hh.tbl, (add)->hh.prev)->next = (add); \ - } else { \ - (head) = (add); \ - } \ - HH_FROM_ELMT((head)->hh.tbl, _hs_iter)->prev = (add); \ - } else { \ - HASH_APPEND_LIST(hh, head, add); \ - } \ - } \ - HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ - HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE_INORDER"); \ -} while (0) - -#define HASH_ADD_KEYPTR_INORDER(hh,head,keyptr,keylen_in,add,cmpfcn) \ -do { \ - unsigned _hs_hashv; \ - HASH_VALUE(keyptr, keylen_in, _hs_hashv); \ - HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, keyptr, keylen_in, _hs_hashv, add, cmpfcn); \ -} while (0) - -#define HASH_ADD_BYHASHVALUE_INORDER(hh,head,fieldname,keylen_in,hashval,add,cmpfcn) \ - HASH_ADD_KEYPTR_BYHASHVALUE_INORDER(hh, head, &((add)->fieldname), keylen_in, hashval, add, cmpfcn) - -#define HASH_ADD_INORDER(hh,head,fieldname,keylen_in,add,cmpfcn) \ - HASH_ADD_KEYPTR_INORDER(hh, head, &((add)->fieldname), keylen_in, add, cmpfcn) - -#define HASH_ADD_KEYPTR_BYHASHVALUE(hh,head,keyptr,keylen_in,hashval,add) \ -do { \ - IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \ - (add)->hh.hashv = (hashval); \ - (add)->hh.key = (const void*) (keyptr); \ - (add)->hh.keylen = (unsigned) (keylen_in); \ - if (!(head)) { \ - (add)->hh.next = NULL; \ - (add)->hh.prev = NULL; \ - HASH_MAKE_TABLE(hh, add, _ha_oomed); \ - IF_HASH_NONFATAL_OOM( if (!_ha_oomed) { ) \ - (head) = (add); \ - IF_HASH_NONFATAL_OOM( } ) \ - } else { \ - (add)->hh.tbl = (head)->hh.tbl; \ - HASH_APPEND_LIST(hh, head, add); \ - } \ - HASH_ADD_TO_TABLE(hh, head, keyptr, keylen_in, hashval, add, _ha_oomed); \ - HASH_FSCK(hh, head, "HASH_ADD_KEYPTR_BYHASHVALUE"); \ -} while (0) - -#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ -do { \ - unsigned _ha_hashv; \ - HASH_VALUE(keyptr, keylen_in, _ha_hashv); \ - HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, keyptr, keylen_in, _ha_hashv, add); \ -} while (0) - -#define HASH_ADD_BYHASHVALUE(hh,head,fieldname,keylen_in,hashval,add) \ - HASH_ADD_KEYPTR_BYHASHVALUE(hh, head, &((add)->fieldname), keylen_in, hashval, add) - -#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ - HASH_ADD_KEYPTR(hh, head, &((add)->fieldname), keylen_in, add) - -#define HASH_TO_BKT(hashv,num_bkts,bkt) \ -do { \ - bkt = ((hashv) & ((num_bkts) - 1U)); \ -} while (0) - -/* delete "delptr" from the hash table. - * "the usual" patch-up process for the app-order doubly-linked-list. - * The use of _hd_hh_del below deserves special explanation. - * These used to be expressed using (delptr) but that led to a bug - * if someone used the same symbol for the head and deletee, like - * HASH_DELETE(hh,users,users); - * We want that to work, but by changing the head (users) below - * we were forfeiting our ability to further refer to the deletee (users) - * in the patch-up process. Solution: use scratch space to - * copy the deletee pointer, then the latter references are via that - * scratch pointer rather than through the repointed (users) symbol. - */ -#define HASH_DELETE(hh,head,delptr) \ - HASH_DELETE_HH(hh, head, &(delptr)->hh) - -#define HASH_DELETE_HH(hh,head,delptrhh) \ -do { \ - struct UT_hash_handle *_hd_hh_del = (delptrhh); \ - if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \ - HASH_BLOOM_FREE((head)->hh.tbl); \ - uthash_free((head)->hh.tbl->buckets, \ - (head)->hh.tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - (head) = NULL; \ - } else { \ - unsigned _hd_bkt; \ - if (_hd_hh_del == (head)->hh.tbl->tail) { \ - (head)->hh.tbl->tail = HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev); \ - } \ - if (_hd_hh_del->prev != NULL) { \ - HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->prev)->next = _hd_hh_del->next; \ - } else { \ - DECLTYPE_ASSIGN(head, _hd_hh_del->next); \ - } \ - if (_hd_hh_del->next != NULL) { \ - HH_FROM_ELMT((head)->hh.tbl, _hd_hh_del->next)->prev = _hd_hh_del->prev; \ - } \ - HASH_TO_BKT(_hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ - HASH_DEL_IN_BKT((head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ - (head)->hh.tbl->num_items--; \ - } \ - HASH_FSCK(hh, head, "HASH_DELETE_HH"); \ -} while (0) - -/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ -#define HASH_FIND_STR(head,findstr,out) \ -do { \ - unsigned _uthash_hfstr_keylen = (unsigned)uthash_strlen(findstr); \ - HASH_FIND(hh, head, findstr, _uthash_hfstr_keylen, out); \ -} while (0) -#define HASH_ADD_STR(head,strfield,add) \ -do { \ - unsigned _uthash_hastr_keylen = (unsigned)uthash_strlen((add)->strfield); \ - HASH_ADD(hh, head, strfield[0], _uthash_hastr_keylen, add); \ -} while (0) -#define HASH_REPLACE_STR(head,strfield,add,replaced) \ -do { \ - unsigned _uthash_hrstr_keylen = (unsigned)uthash_strlen((add)->strfield); \ - HASH_REPLACE(hh, head, strfield[0], _uthash_hrstr_keylen, add, replaced); \ -} while (0) -#define HASH_FIND_INT(head,findint,out) \ - HASH_FIND(hh,head,findint,sizeof(int),out) -#define HASH_ADD_INT(head,intfield,add) \ - HASH_ADD(hh,head,intfield,sizeof(int),add) -#define HASH_REPLACE_INT(head,intfield,add,replaced) \ - HASH_REPLACE(hh,head,intfield,sizeof(int),add,replaced) -#define HASH_FIND_PTR(head,findptr,out) \ - HASH_FIND(hh,head,findptr,sizeof(void *),out) -#define HASH_ADD_PTR(head,ptrfield,add) \ - HASH_ADD(hh,head,ptrfield,sizeof(void *),add) -#define HASH_REPLACE_PTR(head,ptrfield,add,replaced) \ - HASH_REPLACE(hh,head,ptrfield,sizeof(void *),add,replaced) -#define HASH_DEL(head,delptr) \ - HASH_DELETE(hh,head,delptr) - -/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. - * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. - */ -#ifdef HASH_DEBUG -#include /* fprintf, stderr */ -#define HASH_OOPS(...) do { fprintf(stderr, __VA_ARGS__); exit(-1); } while (0) -#define HASH_FSCK(hh,head,where) \ -do { \ - struct UT_hash_handle *_thh; \ - if (head) { \ - unsigned _bkt_i; \ - unsigned _count = 0; \ - char *_prev; \ - for (_bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; ++_bkt_i) { \ - unsigned _bkt_count = 0; \ - _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ - _prev = NULL; \ - while (_thh) { \ - if (_prev != (char*)(_thh->hh_prev)) { \ - HASH_OOPS("%s: invalid hh_prev %p, actual %p\n", \ - (where), (void*)_thh->hh_prev, (void*)_prev); \ - } \ - _bkt_count++; \ - _prev = (char*)(_thh); \ - _thh = _thh->hh_next; \ - } \ - _count += _bkt_count; \ - if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ - HASH_OOPS("%s: invalid bucket count %u, actual %u\n", \ - (where), (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ - } \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("%s: invalid hh item count %u, actual %u\n", \ - (where), (head)->hh.tbl->num_items, _count); \ - } \ - _count = 0; \ - _prev = NULL; \ - _thh = &(head)->hh; \ - while (_thh) { \ - _count++; \ - if (_prev != (char*)_thh->prev) { \ - HASH_OOPS("%s: invalid prev %p, actual %p\n", \ - (where), (void*)_thh->prev, (void*)_prev); \ - } \ - _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ - _thh = (_thh->next ? HH_FROM_ELMT((head)->hh.tbl, _thh->next) : NULL); \ - } \ - if (_count != (head)->hh.tbl->num_items) { \ - HASH_OOPS("%s: invalid app item count %u, actual %u\n", \ - (where), (head)->hh.tbl->num_items, _count); \ - } \ - } \ -} while (0) -#else -#define HASH_FSCK(hh,head,where) -#endif - -/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to - * the descriptor to which this macro is defined for tuning the hash function. - * The app can #include to get the prototype for write(2). */ -#ifdef HASH_EMIT_KEYS -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ -do { \ - unsigned _klen = fieldlen; \ - write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ - write(HASH_EMIT_KEYS, keyptr, (unsigned long)fieldlen); \ -} while (0) -#else -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) -#endif - -/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */ -#define HASH_BER(key,keylen,hashv) \ -do { \ - unsigned _hb_keylen = (unsigned)keylen; \ - const unsigned char *_hb_key = (const unsigned char*)(key); \ - (hashv) = 0; \ - while (_hb_keylen-- != 0U) { \ - (hashv) = (((hashv) << 5) + (hashv)) + *_hb_key++; \ - } \ -} while (0) - - -/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at - * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ -#define HASH_SAX(key,keylen,hashv) \ -do { \ - unsigned _sx_i; \ - const unsigned char *_hs_key = (const unsigned char*)(key); \ - hashv = 0; \ - for (_sx_i=0; _sx_i < keylen; _sx_i++) { \ - hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ - } \ -} while (0) -/* FNV-1a variation */ -#define HASH_FNV(key,keylen,hashv) \ -do { \ - unsigned _fn_i; \ - const unsigned char *_hf_key = (const unsigned char*)(key); \ - (hashv) = 2166136261U; \ - for (_fn_i=0; _fn_i < keylen; _fn_i++) { \ - hashv = hashv ^ _hf_key[_fn_i]; \ - hashv = hashv * 16777619U; \ - } \ -} while (0) - -#define HASH_OAT(key,keylen,hashv) \ -do { \ - unsigned _ho_i; \ - const unsigned char *_ho_key=(const unsigned char*)(key); \ - hashv = 0; \ - for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ - hashv += _ho_key[_ho_i]; \ - hashv += (hashv << 10); \ - hashv ^= (hashv >> 6); \ - } \ - hashv += (hashv << 3); \ - hashv ^= (hashv >> 11); \ - hashv += (hashv << 15); \ -} while (0) - -#define HASH_JEN_MIX(a,b,c) \ -do { \ - a -= b; a -= c; a ^= ( c >> 13 ); \ - b -= c; b -= a; b ^= ( a << 8 ); \ - c -= a; c -= b; c ^= ( b >> 13 ); \ - a -= b; a -= c; a ^= ( c >> 12 ); \ - b -= c; b -= a; b ^= ( a << 16 ); \ - c -= a; c -= b; c ^= ( b >> 5 ); \ - a -= b; a -= c; a ^= ( c >> 3 ); \ - b -= c; b -= a; b ^= ( a << 10 ); \ - c -= a; c -= b; c ^= ( b >> 15 ); \ -} while (0) - -#define HASH_JEN(key,keylen,hashv) \ -do { \ - unsigned _hj_i,_hj_j,_hj_k; \ - unsigned const char *_hj_key=(unsigned const char*)(key); \ - hashv = 0xfeedbeefu; \ - _hj_i = _hj_j = 0x9e3779b9u; \ - _hj_k = (unsigned)(keylen); \ - while (_hj_k >= 12U) { \ - _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ - + ( (unsigned)_hj_key[2] << 16 ) \ - + ( (unsigned)_hj_key[3] << 24 ) ); \ - _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ - + ( (unsigned)_hj_key[6] << 16 ) \ - + ( (unsigned)_hj_key[7] << 24 ) ); \ - hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ - + ( (unsigned)_hj_key[10] << 16 ) \ - + ( (unsigned)_hj_key[11] << 24 ) ); \ - \ - HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ - \ - _hj_key += 12; \ - _hj_k -= 12U; \ - } \ - hashv += (unsigned)(keylen); \ - switch ( _hj_k ) { \ - case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); /* FALLTHROUGH */ \ - case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); /* FALLTHROUGH */ \ - case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); /* FALLTHROUGH */ \ - case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); /* FALLTHROUGH */ \ - case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); /* FALLTHROUGH */ \ - case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); /* FALLTHROUGH */ \ - case 5: _hj_j += _hj_key[4]; /* FALLTHROUGH */ \ - case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); /* FALLTHROUGH */ \ - case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); /* FALLTHROUGH */ \ - case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); /* FALLTHROUGH */ \ - case 1: _hj_i += _hj_key[0]; /* FALLTHROUGH */ \ - default: ; \ - } \ - HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ -} while (0) - -/* The Paul Hsieh hash function */ -#undef get16bits -#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ - || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) -#define get16bits(d) (*((const uint16_t *) (d))) -#endif - -#if !defined (get16bits) -#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ - +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif -#define HASH_SFH(key,keylen,hashv) \ -do { \ - unsigned const char *_sfh_key=(unsigned const char*)(key); \ - uint32_t _sfh_tmp, _sfh_len = (uint32_t)keylen; \ - \ - unsigned _sfh_rem = _sfh_len & 3U; \ - _sfh_len >>= 2; \ - hashv = 0xcafebabeu; \ - \ - /* Main loop */ \ - for (;_sfh_len > 0U; _sfh_len--) { \ - hashv += get16bits (_sfh_key); \ - _sfh_tmp = ((uint32_t)(get16bits (_sfh_key+2)) << 11) ^ hashv; \ - hashv = (hashv << 16) ^ _sfh_tmp; \ - _sfh_key += 2U*sizeof (uint16_t); \ - hashv += hashv >> 11; \ - } \ - \ - /* Handle end cases */ \ - switch (_sfh_rem) { \ - case 3: hashv += get16bits (_sfh_key); \ - hashv ^= hashv << 16; \ - hashv ^= (uint32_t)(_sfh_key[sizeof (uint16_t)]) << 18; \ - hashv += hashv >> 11; \ - break; \ - case 2: hashv += get16bits (_sfh_key); \ - hashv ^= hashv << 11; \ - hashv += hashv >> 17; \ - break; \ - case 1: hashv += *_sfh_key; \ - hashv ^= hashv << 10; \ - hashv += hashv >> 1; \ - break; \ - default: ; \ - } \ - \ - /* Force "avalanching" of final 127 bits */ \ - hashv ^= hashv << 3; \ - hashv += hashv >> 5; \ - hashv ^= hashv << 4; \ - hashv += hashv >> 17; \ - hashv ^= hashv << 25; \ - hashv += hashv >> 6; \ -} while (0) - -/* iterate over items in a known bucket to find desired item */ -#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,hashval,out) \ -do { \ - if ((head).hh_head != NULL) { \ - DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (head).hh_head)); \ - } else { \ - (out) = NULL; \ - } \ - while ((out) != NULL) { \ - if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \ - if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \ - break; \ - } \ - } \ - if ((out)->hh.hh_next != NULL) { \ - DECLTYPE_ASSIGN(out, ELMT_FROM_HH(tbl, (out)->hh.hh_next)); \ - } else { \ - (out) = NULL; \ - } \ - } \ -} while (0) - -/* add an item to a bucket */ -#define HASH_ADD_TO_BKT(head,hh,addhh,oomed) \ -do { \ - UT_hash_bucket *_ha_head = &(head); \ - _ha_head->count++; \ - (addhh)->hh_next = _ha_head->hh_head; \ - (addhh)->hh_prev = NULL; \ - if (_ha_head->hh_head != NULL) { \ - _ha_head->hh_head->hh_prev = (addhh); \ - } \ - _ha_head->hh_head = (addhh); \ - if ((_ha_head->count >= ((_ha_head->expand_mult + 1U) * HASH_BKT_CAPACITY_THRESH)) \ - && !(addhh)->tbl->noexpand) { \ - HASH_EXPAND_BUCKETS(addhh,(addhh)->tbl, oomed); \ - IF_HASH_NONFATAL_OOM( \ - if (oomed) { \ - HASH_DEL_IN_BKT(head,addhh); \ - } \ - ) \ - } \ -} while (0) - -/* remove an item from a given bucket */ -#define HASH_DEL_IN_BKT(head,delhh) \ -do { \ - UT_hash_bucket *_hd_head = &(head); \ - _hd_head->count--; \ - if (_hd_head->hh_head == (delhh)) { \ - _hd_head->hh_head = (delhh)->hh_next; \ - } \ - if ((delhh)->hh_prev) { \ - (delhh)->hh_prev->hh_next = (delhh)->hh_next; \ - } \ - if ((delhh)->hh_next) { \ - (delhh)->hh_next->hh_prev = (delhh)->hh_prev; \ - } \ -} while (0) - -/* Bucket expansion has the effect of doubling the number of buckets - * and redistributing the items into the new buckets. Ideally the - * items will distribute more or less evenly into the new buckets - * (the extent to which this is true is a measure of the quality of - * the hash function as it applies to the key domain). - * - * With the items distributed into more buckets, the chain length - * (item count) in each bucket is reduced. Thus by expanding buckets - * the hash keeps a bound on the chain length. This bounded chain - * length is the essence of how a hash provides constant time lookup. - * - * The calculation of tbl->ideal_chain_maxlen below deserves some - * explanation. First, keep in mind that we're calculating the ideal - * maximum chain length based on the *new* (doubled) bucket count. - * In fractions this is just n/b (n=number of items,b=new num buckets). - * Since the ideal chain length is an integer, we want to calculate - * ceil(n/b). We don't depend on floating point arithmetic in this - * hash, so to calculate ceil(n/b) with integers we could write - * - * ceil(n/b) = (n/b) + ((n%b)?1:0) - * - * and in fact a previous version of this hash did just that. - * But now we have improved things a bit by recognizing that b is - * always a power of two. We keep its base 2 log handy (call it lb), - * so now we can write this with a bit shift and logical AND: - * - * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) - * - */ -#define HASH_EXPAND_BUCKETS(hh,tbl,oomed) \ -do { \ - unsigned _he_bkt; \ - unsigned _he_bkt_i; \ - struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ - UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ - _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ - sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ - if (!_he_new_buckets) { \ - HASH_RECORD_OOM(oomed); \ - } else { \ - uthash_bzero(_he_new_buckets, \ - sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \ - (tbl)->ideal_chain_maxlen = \ - ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \ - ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \ - (tbl)->nonideal_items = 0; \ - for (_he_bkt_i = 0; _he_bkt_i < (tbl)->num_buckets; _he_bkt_i++) { \ - _he_thh = (tbl)->buckets[ _he_bkt_i ].hh_head; \ - while (_he_thh != NULL) { \ - _he_hh_nxt = _he_thh->hh_next; \ - HASH_TO_BKT(_he_thh->hashv, (tbl)->num_buckets * 2U, _he_bkt); \ - _he_newbkt = &(_he_new_buckets[_he_bkt]); \ - if (++(_he_newbkt->count) > (tbl)->ideal_chain_maxlen) { \ - (tbl)->nonideal_items++; \ - if (_he_newbkt->count > _he_newbkt->expand_mult * (tbl)->ideal_chain_maxlen) { \ - _he_newbkt->expand_mult++; \ - } \ - } \ - _he_thh->hh_prev = NULL; \ - _he_thh->hh_next = _he_newbkt->hh_head; \ - if (_he_newbkt->hh_head != NULL) { \ - _he_newbkt->hh_head->hh_prev = _he_thh; \ - } \ - _he_newbkt->hh_head = _he_thh; \ - _he_thh = _he_hh_nxt; \ - } \ - } \ - uthash_free((tbl)->buckets, (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \ - (tbl)->num_buckets *= 2U; \ - (tbl)->log2_num_buckets++; \ - (tbl)->buckets = _he_new_buckets; \ - (tbl)->ineff_expands = ((tbl)->nonideal_items > ((tbl)->num_items >> 1)) ? \ - ((tbl)->ineff_expands+1U) : 0U; \ - if ((tbl)->ineff_expands > 1U) { \ - (tbl)->noexpand = 1; \ - uthash_noexpand_fyi(tbl); \ - } \ - uthash_expand_fyi(tbl); \ - } \ -} while (0) - - -/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ -/* Note that HASH_SORT assumes the hash handle name to be hh. - * HASH_SRT was added to allow the hash handle name to be passed in. */ -#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) -#define HASH_SRT(hh,head,cmpfcn) \ -do { \ - unsigned _hs_i; \ - unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ - struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ - if (head != NULL) { \ - _hs_insize = 1; \ - _hs_looping = 1; \ - _hs_list = &((head)->hh); \ - while (_hs_looping != 0U) { \ - _hs_p = _hs_list; \ - _hs_list = NULL; \ - _hs_tail = NULL; \ - _hs_nmerges = 0; \ - while (_hs_p != NULL) { \ - _hs_nmerges++; \ - _hs_q = _hs_p; \ - _hs_psize = 0; \ - for (_hs_i = 0; _hs_i < _hs_insize; ++_hs_i) { \ - _hs_psize++; \ - _hs_q = ((_hs_q->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ - if (_hs_q == NULL) { \ - break; \ - } \ - } \ - _hs_qsize = _hs_insize; \ - while ((_hs_psize != 0U) || ((_hs_qsize != 0U) && (_hs_q != NULL))) { \ - if (_hs_psize == 0U) { \ - _hs_e = _hs_q; \ - _hs_q = ((_hs_q->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ - _hs_qsize--; \ - } else if ((_hs_qsize == 0U) || (_hs_q == NULL)) { \ - _hs_e = _hs_p; \ - if (_hs_p != NULL) { \ - _hs_p = ((_hs_p->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ - } \ - _hs_psize--; \ - } else if ((cmpfcn( \ - DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_p)), \ - DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl, _hs_q)) \ - )) <= 0) { \ - _hs_e = _hs_p; \ - if (_hs_p != NULL) { \ - _hs_p = ((_hs_p->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_p->next) : NULL); \ - } \ - _hs_psize--; \ - } else { \ - _hs_e = _hs_q; \ - _hs_q = ((_hs_q->next != NULL) ? \ - HH_FROM_ELMT((head)->hh.tbl, _hs_q->next) : NULL); \ - _hs_qsize--; \ - } \ - if ( _hs_tail != NULL ) { \ - _hs_tail->next = ((_hs_e != NULL) ? \ - ELMT_FROM_HH((head)->hh.tbl, _hs_e) : NULL); \ - } else { \ - _hs_list = _hs_e; \ - } \ - if (_hs_e != NULL) { \ - _hs_e->prev = ((_hs_tail != NULL) ? \ - ELMT_FROM_HH((head)->hh.tbl, _hs_tail) : NULL); \ - } \ - _hs_tail = _hs_e; \ - } \ - _hs_p = _hs_q; \ - } \ - if (_hs_tail != NULL) { \ - _hs_tail->next = NULL; \ - } \ - if (_hs_nmerges <= 1U) { \ - _hs_looping = 0; \ - (head)->hh.tbl->tail = _hs_tail; \ - DECLTYPE_ASSIGN(head, ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ - } \ - _hs_insize *= 2U; \ - } \ - HASH_FSCK(hh, head, "HASH_SRT"); \ - } \ -} while (0) - -/* This function selects items from one hash into another hash. - * The end result is that the selected items have dual presence - * in both hashes. There is no copy of the items made; rather - * they are added into the new hash through a secondary hash - * hash handle that must be present in the structure. */ -#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ -do { \ - unsigned _src_bkt, _dst_bkt; \ - void *_last_elt = NULL, *_elt; \ - UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ - ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ - if ((src) != NULL) { \ - for (_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ - for (_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ - _src_hh != NULL; \ - _src_hh = _src_hh->hh_next) { \ - _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ - if (cond(_elt)) { \ - IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \ - _dst_hh = (UT_hash_handle*)(void*)(((char*)_elt) + _dst_hho); \ - _dst_hh->key = _src_hh->key; \ - _dst_hh->keylen = _src_hh->keylen; \ - _dst_hh->hashv = _src_hh->hashv; \ - _dst_hh->prev = _last_elt; \ - _dst_hh->next = NULL; \ - if (_last_elt_hh != NULL) { \ - _last_elt_hh->next = _elt; \ - } \ - if ((dst) == NULL) { \ - DECLTYPE_ASSIGN(dst, _elt); \ - HASH_MAKE_TABLE(hh_dst, dst, _hs_oomed); \ - IF_HASH_NONFATAL_OOM( \ - if (_hs_oomed) { \ - uthash_nonfatal_oom(_elt); \ - (dst) = NULL; \ - continue; \ - } \ - ) \ - } else { \ - _dst_hh->tbl = (dst)->hh_dst.tbl; \ - } \ - HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ - HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt], hh_dst, _dst_hh, _hs_oomed); \ - (dst)->hh_dst.tbl->num_items++; \ - IF_HASH_NONFATAL_OOM( \ - if (_hs_oomed) { \ - HASH_ROLLBACK_BKT(hh_dst, dst, _dst_hh); \ - HASH_DELETE_HH(hh_dst, dst, _dst_hh); \ - _dst_hh->tbl = NULL; \ - uthash_nonfatal_oom(_elt); \ - continue; \ - } \ - ) \ - HASH_BLOOM_ADD(_dst_hh->tbl, _dst_hh->hashv); \ - _last_elt = _elt; \ - _last_elt_hh = _dst_hh; \ - } \ - } \ - } \ - } \ - HASH_FSCK(hh_dst, dst, "HASH_SELECT"); \ -} while (0) - -#define HASH_CLEAR(hh,head) \ -do { \ - if ((head) != NULL) { \ - HASH_BLOOM_FREE((head)->hh.tbl); \ - uthash_free((head)->hh.tbl->buckets, \ - (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ - uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ - (head) = NULL; \ - } \ -} while (0) - -#define HASH_OVERHEAD(hh,head) \ - (((head) != NULL) ? ( \ - (size_t)(((head)->hh.tbl->num_items * sizeof(UT_hash_handle)) + \ - ((head)->hh.tbl->num_buckets * sizeof(UT_hash_bucket)) + \ - sizeof(UT_hash_table) + \ - (HASH_BLOOM_BYTELEN))) : 0U) - -#ifdef NO_DECLTYPE -#define HASH_ITER(hh,head,el,tmp) \ -for(((el)=(head)), ((*(char**)(&(tmp)))=(char*)((head!=NULL)?(head)->hh.next:NULL)); \ - (el) != NULL; ((el)=(tmp)), ((*(char**)(&(tmp)))=(char*)((tmp!=NULL)?(tmp)->hh.next:NULL))) -#else -#define HASH_ITER(hh,head,el,tmp) \ -for(((el)=(head)), ((tmp)=DECLTYPE(el)((head!=NULL)?(head)->hh.next:NULL)); \ - (el) != NULL; ((el)=(tmp)), ((tmp)=DECLTYPE(el)((tmp!=NULL)?(tmp)->hh.next:NULL))) -#endif - -/* obtain a count of items in the hash */ -#define HASH_COUNT(head) HASH_CNT(hh,head) -#define HASH_CNT(hh,head) ((head != NULL)?((head)->hh.tbl->num_items):0U) - -typedef struct UT_hash_bucket { - struct UT_hash_handle *hh_head; - unsigned count; - - /* expand_mult is normally set to 0. In this situation, the max chain length - * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If - * the bucket's chain exceeds this length, bucket expansion is triggered). - * However, setting expand_mult to a non-zero value delays bucket expansion - * (that would be triggered by additions to this particular bucket) - * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. - * (The multiplier is simply expand_mult+1). The whole idea of this - * multiplier is to reduce bucket expansions, since they are expensive, in - * situations where we know that a particular bucket tends to be overused. - * It is better to let its chain length grow to a longer yet-still-bounded - * value, than to do an O(n) bucket expansion too often. - */ - unsigned expand_mult; - -} UT_hash_bucket; - -/* random signature used only to find hash tables in external analysis */ -#define HASH_SIGNATURE 0xa0111fe1u -#define HASH_BLOOM_SIGNATURE 0xb12220f2u - -typedef struct UT_hash_table { - UT_hash_bucket *buckets; - unsigned num_buckets, log2_num_buckets; - unsigned num_items; - struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ - ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ - - /* in an ideal situation (all buckets used equally), no bucket would have - * more than ceil(#items/#buckets) items. that's the ideal chain length. */ - unsigned ideal_chain_maxlen; - - /* nonideal_items is the number of items in the hash whose chain position - * exceeds the ideal chain maxlen. these items pay the penalty for an uneven - * hash distribution; reaching them in a chain traversal takes >ideal steps */ - unsigned nonideal_items; - - /* ineffective expands occur when a bucket doubling was performed, but - * afterward, more than half the items in the hash had nonideal chain - * positions. If this happens on two consecutive expansions we inhibit any - * further expansion, as it's not helping; this happens when the hash - * function isn't a good fit for the key domain. When expansion is inhibited - * the hash will still work, albeit no longer in constant time. */ - unsigned ineff_expands, noexpand; - - uint32_t signature; /* used only to find hash tables in external analysis */ -#ifdef HASH_BLOOM - uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ - uint8_t *bloom_bv; - uint8_t bloom_nbits; -#endif - -} UT_hash_table; - -typedef struct UT_hash_handle { - struct UT_hash_table *tbl; - void *prev; /* prev element in app order */ - void *next; /* next element in app order */ - struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ - struct UT_hash_handle *hh_next; /* next hh in bucket order */ - const void *key; /* ptr to enclosing struct's key */ - unsigned keylen; /* enclosing struct's key len */ - unsigned hashv; /* result of hash-fcn(key) */ -} UT_hash_handle; - -#endif /* UTHASH_H */ diff --git a/ModelicaExternalC/C-Sources/win32_dirent.c b/ModelicaExternalC/C-Sources/win32_dirent.c deleted file mode 100644 index 694b2ddbd..000000000 --- a/ModelicaExternalC/C-Sources/win32_dirent.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * dirent.c - * - * Derived from DIRLIB.C by Matt J. Weinstein - * This note appears in the DIRLIB.H - * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89 - * - * Updated by Jeremy Bettis - * Significantly revised and rewinddir, seekdir and telldir added by Colin - * Peters - * - * Martin Otter, 2001/01/06: - * - Call to "GetFileAttributes" and "#include " - * replaced by call to "_stat" because this is part of libc.a - * - If no more file found, _findnext sets errno. - * Since this is not an error, errno is reset to zero. - * (otherwise the calling routine cannot check, whether an error - * occurred within this function) - * - Initializing the search with findfirst is moved from "readdir" - * to "opendir", in order that in the calling function the - * current directory can be changed after "opendir". - */ - -#if defined(_WIN32) && !defined(NO_FILE_SYSTEM) && !defined(__WATCOMC__) && !defined(__BORLANDC__) && !defined(__MINGW32__) && !defined(__CYGWIN__) - -#include -#include -#include -#include -#include -#include -#include - -#include "win32_dirent.h" -#define SUFFIX "*" -#define SLASH "\\" - -/* - * opendir - * - * Returns a pointer to a DIR structure appropriately filled in to begin - * searching a directory. - */ -DIR * -opendir (const char *szPath) -{ - DIR *nd; - - errno = 0; - - if (!szPath) - { - errno = EFAULT; - return (DIR *) 0; - } - - if (szPath[0] == '\0') - { - errno = ENOTDIR; - return (DIR *) 0; - } - - /* Attempt to determine if the given path really is a directory. */ - { -#if defined(_MSC_VER) - struct _stat fileInfo; - if ( _stat(szPath, &fileInfo) != 0 ) { -#else - struct stat fileInfo; - if ( stat(szPath, &fileInfo) != 0 ) { -#endif - /* call GetLastError for more error info */ - errno = ENOENT; - return (DIR *) 0; - } - - if ( !(fileInfo.st_mode & S_IFDIR) ) { - /* Error, entry exists but not a directory. */ - errno = ENOTDIR; - return (DIR *) 0; - } - } - - /* Allocate enough space to store DIR structure and the complete - * directory path given. */ - nd = (DIR *) malloc (sizeof (DIR) + strlen (szPath) + strlen (SLASH) + - strlen (SUFFIX)); - - if (!nd) - { - /* Error, out of memory. */ - errno = ENOMEM; - return (DIR *) 0; - } - - /* Create the search expression. */ - strcpy (nd->dd_name, szPath); - - /* Add on a slash if the path does not end with one. */ - if (nd->dd_name[0] != '\0' && - nd->dd_name[strlen (nd->dd_name) - 1] != '/' && - nd->dd_name[strlen (nd->dd_name) - 1] != '\\') - { - strcat (nd->dd_name, SLASH); - } - - /* Add on the search pattern */ - strcat (nd->dd_name, SUFFIX); - - /* Initialize handle to -1 so that a premature closedir doesn't try - * to call _findclose on it. */ - nd->dd_handle = -1; - - /* Initialize the status. */ - nd->dd_stat = 0; - - /* Initialize the dirent structure. ino and reclen are invalid under - * Win32, and name simply points at the appropriate part of the - * findfirst_t structure. */ - nd->dd_dir.d_ino = 0; - nd->dd_dir.d_reclen = 0; - nd->dd_dir.d_namlen = 0; - nd->dd_dir.d_name = nd->dd_dta.name; - - /* Start the search, in order that the user may still - change the current directory afterwards - */ - nd->dd_handle = (find_t)_findfirst (nd->dd_name, &(nd->dd_dta)); - if (nd->dd_handle == -1) { - /* Whoops! Seems there are no files in that - * directory. */ - nd->dd_stat = -1; - } else { - nd->dd_stat = 1; - } - - return nd; -} - -/* - * readdir - * - * Return a pointer to a dirent structure filled with the information on the - * next entry in the directory. - */ -struct dirent * -readdir (DIR * dirp) -{ - errno = 0; - - /* Check for valid DIR struct. */ - if (!dirp) - { - errno = EFAULT; - return (struct dirent *) 0; - } - - if (dirp->dd_dir.d_name != dirp->dd_dta.name) - { - /* The structure does not seem to be set up correctly. */ - errno = EINVAL; - return (struct dirent *) 0; - } - - if (dirp->dd_stat < 0) - { - /* We have already returned all files in the directory - * (or the structure has an invalid dd_stat). */ - return (struct dirent *) 0; - } - else - { - /* Get the next search entry. */ - if (_findnext (dirp->dd_handle, &(dirp->dd_dta))) - { - /* We are off the end */ - errno = 0; - _findclose (dirp->dd_handle); - dirp->dd_handle = -1; - dirp->dd_stat = -1; - } - else - { - /* Update the status to indicate the correct - * number. */ - dirp->dd_stat++; - } - } - - if (dirp->dd_stat > 0) - { - /* Successfully got an entry. Everything about the file is - * already appropriately filled in except the length of the - * file name. */ - dirp->dd_dir.d_namlen = (unsigned short)strlen (dirp->dd_dir.d_name); - return &dirp->dd_dir; - } - - return (struct dirent *) 0; -} - -/* - * closedir - * - * Frees up resources allocated by opendir. - */ -int -closedir (DIR * dirp) -{ - int rc; - - errno = 0; - rc = 0; - - if (!dirp) - { - errno = EFAULT; - return -1; - } - - if (dirp->dd_handle != -1) - { - rc = _findclose (dirp->dd_handle); - } - - /* Delete the dir structure. */ - free (dirp); - - return rc; -} - -/* - * rewinddir - * - * Return to the beginning of the directory "stream". We simply call findclose - * and then reset things like an opendir. - */ -void -rewinddir (DIR * dirp) -{ - errno = 0; - - if (!dirp) - { - errno = EFAULT; - return; - } - - if (dirp->dd_handle != -1) - { - _findclose (dirp->dd_handle); - } - - dirp->dd_handle = -1; - dirp->dd_stat = 0; -} - -/* - * telldir - * - * Returns the "position" in the "directory stream" which can be used with - * seekdir to go back to an old entry. We simply return the value in stat. - */ -long -telldir (DIR * dirp) -{ - errno = 0; - - if (!dirp) - { - errno = EFAULT; - return -1; - } - return dirp->dd_stat; -} - -/* - * seekdir - * - * Seek to an entry previously returned by telldir. We rewind the directory - * and call readdir repeatedly until either dd_stat is the position number - * or -1 (off the end). This is not perfect, in that the directory may - * have changed while we weren't looking. But that is probably the case with - * any such system. - */ -void -seekdir (DIR * dirp, long lPos) -{ - errno = 0; - - if (!dirp) - { - errno = EFAULT; - return; - } - - if (lPos < -1) - { - /* Seeking to an invalid position. */ - errno = EINVAL; - return; - } - else if (lPos == -1) - { - /* Seek past end. */ - if (dirp->dd_handle != -1) - { - _findclose (dirp->dd_handle); - } - dirp->dd_handle = -1; - dirp->dd_stat = -1; - } - else - { - /* Rewind and read forward to the appropriate index. */ - rewinddir (dirp); - - while ((dirp->dd_stat < lPos) && readdir (dirp)) - ; - } -} - -#endif diff --git a/ModelicaExternalC/C-Sources/win32_dirent.h b/ModelicaExternalC/C-Sources/win32_dirent.h deleted file mode 100644 index 71254759c..000000000 --- a/ModelicaExternalC/C-Sources/win32_dirent.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * DIRENT.H (formerly DIRLIB.H) - * - * by M. J. Weinstein Released to public domain 1-Jan-89 - * - * Because I have heard that this feature (opendir, readdir, closedir) - * it so useful for programmers coming from UNIX or attempting to port - * UNIX code, and because it is reasonably light weight, I have included - * it in the Mingw32 package. I have also added an implementation of - * rewinddir, seekdir and telldir. - * - Colin Peters - * - * This code is distributed in the hope that is will be useful but - * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY - * DISCLAIMED. This includes but is not limited to warranties of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * Martin Otter, 2001/01/06: - * Removed: #ifndef __STRICT_ANSI__ - * #include <_mingw.h> - * since not needed in Modelica - */ - -#ifndef _WIN32_DIRENT_H_ -#define _WIN32_DIRENT_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct dirent -{ - long d_ino; /* Always zero. */ - unsigned short d_reclen; /* Always zero. */ - unsigned short d_namlen; /* Length of name in d_name. */ - char* d_name; /* File name. */ - /* NOTE: The name in the dirent structure points to the name in the - * finddata_t structure in the DIR. */ -}; - -#if (defined(_MSC_VER) && _MSC_VER >= 1300) || defined(__MINGW32__) -typedef intptr_t find_t; -#else -typedef long find_t; -#endif - -/* - * This is an internal data structure. Good programmers will not use it - * except as an argument to one of the functions below. - */ -typedef struct -{ - /* disk transfer area for this dir */ - struct _finddata_t dd_dta; - - /* dirent struct to return from dir (NOTE: this makes this thread - * safe as long as only one thread uses a particular DIR struct at - * a time) */ - struct dirent dd_dir; - - /* _findnext handle */ - find_t dd_handle; - - /* - * Status of search: - * 0 = not started yet (next entry to read is first entry) - * -1 = off the end - * positive = 0 based index of next entry - */ - short dd_stat; - - /* given path for dir with search pattern (struct is extended) */ - char dd_name[1]; -} DIR; - -DIR* opendir (const char*); -struct dirent* readdir (DIR*); -int closedir (DIR*); -void rewinddir (DIR*); -long telldir (DIR*); -void seekdir (DIR*, long); - -#ifdef __cplusplus -} -#endif - -#endif /* Not _WIN32_DIRENT_H_ */ diff --git a/ModelicaExternalC/C-Sources/zlib/ChangeLog b/ModelicaExternalC/C-Sources/zlib/ChangeLog deleted file mode 100644 index 30199a65a..000000000 --- a/ModelicaExternalC/C-Sources/zlib/ChangeLog +++ /dev/null @@ -1,1515 +0,0 @@ - - ChangeLog file for zlib - -Changes in 1.2.11 (15 Jan 2017) -- Fix deflate stored bug when pulling last block from window -- Permit immediate deflateParams changes before any deflate input - -Changes in 1.2.10 (2 Jan 2017) -- Avoid warnings on snprintf() return value -- Fix bug in deflate_stored() for zero-length input -- Fix bug in gzwrite.c that produced corrupt gzip files -- Remove files to be installed before copying them in Makefile.in -- Add warnings when compiling with assembler code - -Changes in 1.2.9 (31 Dec 2016) -- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] -- Improve contrib/blast to return unused bytes -- Assure that gzoffset() is correct when appending -- Improve compress() and uncompress() to support large lengths -- Fix bug in test/example.c where error code not saved -- Remedy Coverity warning [Randers-Pehrson] -- Improve speed of gzprintf() in transparent mode -- Fix inflateInit2() bug when windowBits is 16 or 32 -- Change DEBUG macro to ZLIB_DEBUG -- Avoid uninitialized access by gzclose_w() -- Allow building zlib outside of the source directory -- Fix bug that accepted invalid zlib header when windowBits is zero -- Fix gzseek() problem on MinGW due to buggy _lseeki64 there -- Loop on write() calls in gzwrite.c in case of non-blocking I/O -- Add --warn (-w) option to ./configure for more compiler warnings -- Reject a window size of 256 bytes if not using the zlib wrapper -- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE -- Add --debug (-d) option to ./configure to define ZLIB_DEBUG -- Fix bugs in creating a very large gzip header -- Add uncompress2() function, which returns the input size used -- Assure that deflateParams() will not switch functions mid-block -- Dramatically speed up deflation for level 0 (storing) -- Add gzfread(), duplicating the interface of fread() -- Add gzfwrite(), duplicating the interface of fwrite() -- Add deflateGetDictionary() function -- Use snprintf() for later versions of Microsoft C -- Fix *Init macros to use z_ prefix when requested -- Replace as400 with os400 for OS/400 support [Monnerat] -- Add crc32_z() and adler32_z() functions with size_t lengths -- Update Visual Studio project files [AraHaan] - -Changes in 1.2.8 (28 Apr 2013) -- Update contrib/minizip/iowin32.c for Windows RT [Vollant] -- Do not force Z_CONST for C++ -- Clean up contrib/vstudio [Roß] -- Correct spelling error in zlib.h -- Fix mixed line endings in contrib/vstudio - -Changes in 1.2.7.3 (13 Apr 2013) -- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc - -Changes in 1.2.7.2 (13 Apr 2013) -- Change check for a four-byte type back to hexadecimal -- Fix typo in win32/Makefile.msc -- Add casts in gzwrite.c for pointer differences - -Changes in 1.2.7.1 (24 Mar 2013) -- Replace use of unsafe string functions with snprintf if available -- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] -- Fix gzgetc undefine when Z_PREFIX set [Turk] -- Eliminate use of mktemp in Makefile (not always available) -- Fix bug in 'F' mode for gzopen() -- Add inflateGetDictionary() function -- Correct comment in deflate.h -- Use _snprintf for snprintf in Microsoft C -- On Darwin, only use /usr/bin/libtool if libtool is not Apple -- Delete "--version" file if created by "ar --version" [Richard G.] -- Fix configure check for veracity of compiler error return codes -- Fix CMake compilation of static lib for MSVC2010 x64 -- Remove unused variable in infback9.c -- Fix argument checks in gzlog_compress() and gzlog_write() -- Clean up the usage of z_const and respect const usage within zlib -- Clean up examples/gzlog.[ch] comparisons of different types -- Avoid shift equal to bits in type (caused endless loop) -- Fix uninitialized value bug in gzputc() introduced by const patches -- Fix memory allocation error in examples/zran.c [Nor] -- Fix bug where gzopen(), gzclose() would write an empty file -- Fix bug in gzclose() when gzwrite() runs out of memory -- Check for input buffer malloc failure in examples/gzappend.c -- Add note to contrib/blast to use binary mode in stdio -- Fix comparisons of differently signed integers in contrib/blast -- Check for invalid code length codes in contrib/puff -- Fix serious but very rare decompression bug in inftrees.c -- Update inflateBack() comments, since inflate() can be faster -- Use underscored I/O function names for WINAPI_FAMILY -- Add _tr_flush_bits to the external symbols prefixed by --zprefix -- Add contrib/vstudio/vc10 pre-build step for static only -- Quote --version-script argument in CMakeLists.txt -- Don't specify --version-script on Apple platforms in CMakeLists.txt -- Fix casting error in contrib/testzlib/testzlib.c -- Fix types in contrib/minizip to match result of get_crc_table() -- Simplify contrib/vstudio/vc10 with 'd' suffix -- Add TOP support to win32/Makefile.msc -- Suport i686 and amd64 assembler builds in CMakeLists.txt -- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h -- Add vc11 and vc12 build files to contrib/vstudio -- Add gzvprintf() as an undocumented function in zlib -- Fix configure for Sun shell -- Remove runtime check in configure for four-byte integer type -- Add casts and consts to ease user conversion to C++ -- Add man pages for minizip and miniunzip -- In Makefile uninstall, don't rm if preceding cd fails -- Do not return Z_BUF_ERROR if deflateParam() has nothing to write - -Changes in 1.2.7 (2 May 2012) -- Replace use of memmove() with a simple copy for portability -- Test for existence of strerror -- Restore gzgetc_ for backward compatibility with 1.2.6 -- Fix build with non-GNU make on Solaris -- Require gcc 4.0 or later on Mac OS X to use the hidden attribute -- Include unistd.h for Watcom C -- Use __WATCOMC__ instead of __WATCOM__ -- Do not use the visibility attribute if NO_VIZ defined -- Improve the detection of no hidden visibility attribute -- Avoid using __int64 for gcc or solo compilation -- Cast to char * in gzprintf to avoid warnings [Zinser] -- Fix make_vms.com for VAX [Zinser] -- Don't use library or built-in byte swaps -- Simplify test and use of gcc hidden attribute -- Fix bug in gzclose_w() when gzwrite() fails to allocate memory -- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() -- Fix bug in test/minigzip.c for configure --solo -- Fix contrib/vstudio project link errors [Mohanathas] -- Add ability to choose the builder in make_vms.com [Schweda] -- Add DESTDIR support to mingw32 win32/Makefile.gcc -- Fix comments in win32/Makefile.gcc for proper usage -- Allow overriding the default install locations for cmake -- Generate and install the pkg-config file with cmake -- Build both a static and a shared version of zlib with cmake -- Include version symbols for cmake builds -- If using cmake with MSVC, add the source directory to the includes -- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] -- Move obsolete emx makefile to old [Truta] -- Allow the use of -Wundef when compiling or using zlib -- Avoid the use of the -u option with mktemp -- Improve inflate() documentation on the use of Z_FINISH -- Recognize clang as gcc -- Add gzopen_w() in Windows for wide character path names -- Rename zconf.h in CMakeLists.txt to move it out of the way -- Add source directory in CMakeLists.txt for building examples -- Look in build directory for zlib.pc in CMakeLists.txt -- Remove gzflags from zlibvc.def in vc9 and vc10 -- Fix contrib/minizip compilation in the MinGW environment -- Update ./configure for Solaris, support --64 [Mooney] -- Remove -R. from Solaris shared build (possible security issue) -- Avoid race condition for parallel make (-j) running example -- Fix type mismatch between get_crc_table() and crc_table -- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] -- Fix the path to zlib.map in CMakeLists.txt -- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] -- Add instructions to win32/Makefile.gcc for shared install [Torri] - -Changes in 1.2.6.1 (12 Feb 2012) -- Avoid the use of the Objective-C reserved name "id" -- Include io.h in gzguts.h for Microsoft compilers -- Fix problem with ./configure --prefix and gzgetc macro -- Include gz_header definition when compiling zlib solo -- Put gzflags() functionality back in zutil.c -- Avoid library header include in crc32.c for Z_SOLO -- Use name in GCC_CLASSIC as C compiler for coverage testing, if set -- Minor cleanup in contrib/minizip/zip.c [Vollant] -- Update make_vms.com [Zinser] -- Remove unnecessary gzgetc_ function -- Use optimized byte swap operations for Microsoft and GNU [Snyder] -- Fix minor typo in zlib.h comments [Rzesniowiecki] - -Changes in 1.2.6 (29 Jan 2012) -- Update the Pascal interface in contrib/pascal -- Fix function numbers for gzgetc_ in zlibvc.def files -- Fix configure.ac for contrib/minizip [Schiffer] -- Fix large-entry detection in minizip on 64-bit systems [Schiffer] -- Have ./configure use the compiler return code for error indication -- Fix CMakeLists.txt for cross compilation [McClure] -- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] -- Fix compilation of contrib/minizip on FreeBSD [Marquez] -- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] -- Include io.h for Turbo C / Borland C on all platforms [Truta] -- Make version explicit in contrib/minizip/configure.ac [Bosmans] -- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] -- Minor cleanup up contrib/minizip/unzip.c [Vollant] -- Fix bug when compiling minizip with C++ [Vollant] -- Protect for long name and extra fields in contrib/minizip [Vollant] -- Avoid some warnings in contrib/minizip [Vollant] -- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip -- Add missing libs to minizip linker command -- Add support for VPATH builds in contrib/minizip -- Add an --enable-demos option to contrib/minizip/configure -- Add the generation of configure.log by ./configure -- Exit when required parameters not provided to win32/Makefile.gcc -- Have gzputc return the character written instead of the argument -- Use the -m option on ldconfig for BSD systems [Tobias] -- Correct in zlib.map when deflateResetKeep was added - -Changes in 1.2.5.3 (15 Jan 2012) -- Restore gzgetc function for binary compatibility -- Do not use _lseeki64 under Borland C++ [Truta] -- Update win32/Makefile.msc to build test/*.c [Truta] -- Remove old/visualc6 given CMakefile and other alternatives -- Update AS400 build files and documentation [Monnerat] -- Update win32/Makefile.gcc to build test/*.c [Truta] -- Permit stronger flushes after Z_BLOCK flushes -- Avoid extraneous empty blocks when doing empty flushes -- Permit Z_NULL arguments to deflatePending -- Allow deflatePrime() to insert bits in the middle of a stream -- Remove second empty static block for Z_PARTIAL_FLUSH -- Write out all of the available bits when using Z_BLOCK -- Insert the first two strings in the hash table after a flush - -Changes in 1.2.5.2 (17 Dec 2011) -- fix ld error: unable to find version dependency 'ZLIB_1.2.5' -- use relative symlinks for shared libs -- Avoid searching past window for Z_RLE strategy -- Assure that high-water mark initialization is always applied in deflate -- Add assertions to fill_window() in deflate.c to match comments -- Update python link in README -- Correct spelling error in gzread.c -- Fix bug in gzgets() for a concatenated empty gzip stream -- Correct error in comment for gz_make() -- Change gzread() and related to ignore junk after gzip streams -- Allow gzread() and related to continue after gzclearerr() -- Allow gzrewind() and gzseek() after a premature end-of-file -- Simplify gzseek() now that raw after gzip is ignored -- Change gzgetc() to a macro for speed (~40% speedup in testing) -- Fix gzclose() to return the actual error last encountered -- Always add large file support for windows -- Include zconf.h for windows large file support -- Include zconf.h.cmakein for windows large file support -- Update zconf.h.cmakein on make distclean -- Merge vestigial vsnprintf determination from zutil.h to gzguts.h -- Clarify how gzopen() appends in zlib.h comments -- Correct documentation of gzdirect() since junk at end now ignored -- Add a transparent write mode to gzopen() when 'T' is in the mode -- Update python link in zlib man page -- Get inffixed.h and MAKEFIXED result to match -- Add a ./config --solo option to make zlib subset with no library use -- Add undocumented inflateResetKeep() function for CAB file decoding -- Add --cover option to ./configure for gcc coverage testing -- Add #define ZLIB_CONST option to use const in the z_stream interface -- Add comment to gzdopen() in zlib.h to use dup() when using fileno() -- Note behavior of uncompress() to provide as much data as it can -- Add files in contrib/minizip to aid in building libminizip -- Split off AR options in Makefile.in and configure -- Change ON macro to Z_ARG to avoid application conflicts -- Facilitate compilation with Borland C++ for pragmas and vsnprintf -- Include io.h for Turbo C / Borland C++ -- Move example.c and minigzip.c to test/ -- Simplify incomplete code table filling in inflate_table() -- Remove code from inflate.c and infback.c that is impossible to execute -- Test the inflate code with full coverage -- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) -- Add deflateResetKeep and fix inflateResetKeep to retain dictionary -- Fix gzwrite.c to accommodate reduced memory zlib compilation -- Have inflate() with Z_FINISH avoid the allocation of a window -- Do not set strm->adler when doing raw inflate -- Fix gzeof() to behave just like feof() when read is not past end of file -- Fix bug in gzread.c when end-of-file is reached -- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF -- Document gzread() capability to read concurrently written files -- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] - -Changes in 1.2.5.1 (10 Sep 2011) -- Update FAQ entry on shared builds (#13) -- Avoid symbolic argument to chmod in Makefile.in -- Fix bug and add consts in contrib/puff [Oberhumer] -- Update contrib/puff/zeros.raw test file to have all block types -- Add full coverage test for puff in contrib/puff/Makefile -- Fix static-only-build install in Makefile.in -- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] -- Add libz.a dependency to shared in Makefile.in for parallel builds -- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out -- Replace $(...) with `...` in configure for non-bash sh [Bowler] -- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] -- Add solaris* to Linux* in configure to allow gcc use [Groffen] -- Add *bsd* to Linux* case in configure [Bar-Lev] -- Add inffast.obj to dependencies in win32/Makefile.msc -- Correct spelling error in deflate.h [Kohler] -- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc -- Add test to configure for GNU C looking for gcc in output of $cc -v -- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] -- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not -- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense -- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) -- Make stronger test in zconf.h to include unistd.h for LFS -- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] -- Fix zlib.h LFS support when Z_PREFIX used -- Add updated as400 support (removed from old) [Monnerat] -- Avoid deflate sensitivity to volatile input data -- Avoid division in adler32_combine for NO_DIVIDE -- Clarify the use of Z_FINISH with deflateBound() amount of space -- Set binary for output file in puff.c -- Use u4 type for crc_table to avoid conversion warnings -- Apply casts in zlib.h to avoid conversion warnings -- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] -- Improve inflateSync() documentation to note indeterminancy -- Add deflatePending() function to return the amount of pending output -- Correct the spelling of "specification" in FAQ [Randers-Pehrson] -- Add a check in configure for stdarg.h, use for gzprintf() -- Check that pointers fit in ints when gzprint() compiled old style -- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] -- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] -- Add debug records in assmebler code [Londer] -- Update RFC references to use http://tools.ietf.org/html/... [Li] -- Add --archs option, use of libtool to configure for Mac OS X [Borstel] - -Changes in 1.2.5 (19 Apr 2010) -- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] -- Default to libdir as sharedlibdir in configure [Nieder] -- Update copyright dates on modified source files -- Update trees.c to be able to generate modified trees.h -- Exit configure for MinGW, suggesting win32/Makefile.gcc -- Check for NULL path in gz_open [Homurlu] - -Changes in 1.2.4.5 (18 Apr 2010) -- Set sharedlibdir in configure [Torok] -- Set LDFLAGS in Makefile.in [Bar-Lev] -- Avoid mkdir objs race condition in Makefile.in [Bowler] -- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays -- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C -- Don't use hidden attribute when it is a warning generator (e.g. Solaris) - -Changes in 1.2.4.4 (18 Apr 2010) -- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] -- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty -- Try to use bash or ksh regardless of functionality of /bin/sh -- Fix configure incompatibility with NetBSD sh -- Remove attempt to run under bash or ksh since have better NetBSD fix -- Fix win32/Makefile.gcc for MinGW [Bar-Lev] -- Add diagnostic messages when using CROSS_PREFIX in configure -- Added --sharedlibdir option to configure [Weigelt] -- Use hidden visibility attribute when available [Frysinger] - -Changes in 1.2.4.3 (10 Apr 2010) -- Only use CROSS_PREFIX in configure for ar and ranlib if they exist -- Use CROSS_PREFIX for nm [Bar-Lev] -- Assume _LARGEFILE64_SOURCE defined is equivalent to true -- Avoid use of undefined symbols in #if with && and || -- Make *64 prototypes in gzguts.h consistent with functions -- Add -shared load option for MinGW in configure [Bowler] -- Move z_off64_t to public interface, use instead of off64_t -- Remove ! from shell test in configure (not portable to Solaris) -- Change +0 macro tests to -0 for possibly increased portability - -Changes in 1.2.4.2 (9 Apr 2010) -- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 -- Really provide prototypes for *64 functions when building without LFS -- Only define unlink() in minigzip.c if unistd.h not included -- Update README to point to contrib/vstudio project files -- Move projects/vc6 to old/ and remove projects/ -- Include stdlib.h in minigzip.c for setmode() definition under WinCE -- Clean up assembler builds in win32/Makefile.msc [Rowe] -- Include sys/types.h for Microsoft for off_t definition -- Fix memory leak on error in gz_open() -- Symbolize nm as $NM in configure [Weigelt] -- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] -- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined -- Fix bug in gzeof() to take into account unused input data -- Avoid initialization of structures with variables in puff.c -- Updated win32/README-WIN32.txt [Rowe] - -Changes in 1.2.4.1 (28 Mar 2010) -- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] -- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] -- Restore "for debugging" comment on sprintf() in gzlib.c -- Remove fdopen for MVS from gzguts.h -- Put new README-WIN32.txt in win32 [Rowe] -- Add check for shell to configure and invoke another shell if needed -- Fix big fat stinking bug in gzseek() on uncompressed files -- Remove vestigial F_OPEN64 define in zutil.h -- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE -- Avoid errors on non-LFS systems when applications define LFS macros -- Set EXE to ".exe" in configure for MINGW [Kahle] -- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] -- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] -- Add DLL install in win32/makefile.gcc [Bar-Lev] -- Allow Linux* or linux* from uname in configure [Bar-Lev] -- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] -- Add cross-compilation prefixes to configure [Bar-Lev] -- Match type exactly in gz_load() invocation in gzread.c -- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func -- Provide prototypes for *64 functions when building zlib without LFS -- Don't use -lc when linking shared library on MinGW -- Remove errno.h check in configure and vestigial errno code in zutil.h - -Changes in 1.2.4 (14 Mar 2010) -- Fix VER3 extraction in configure for no fourth subversion -- Update zlib.3, add docs to Makefile.in to make .pdf out of it -- Add zlib.3.pdf to distribution -- Don't set error code in gzerror() if passed pointer is NULL -- Apply destination directory fixes to CMakeLists.txt [Lowman] -- Move #cmakedefine's to a new zconf.in.cmakein -- Restore zconf.h for builds that don't use configure or cmake -- Add distclean to dummy Makefile for convenience -- Update and improve INDEX, README, and FAQ -- Update CMakeLists.txt for the return of zconf.h [Lowman] -- Update contrib/vstudio/vc9 and vc10 [Vollant] -- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc -- Apply license and readme changes to contrib/asm686 [Raiter] -- Check file name lengths and add -c option in minigzip.c [Li] -- Update contrib/amd64 and contrib/masmx86/ [Vollant] -- Avoid use of "eof" parameter in trees.c to not shadow library variable -- Update make_vms.com for removal of zlibdefs.h [Zinser] -- Update assembler code and vstudio projects in contrib [Vollant] -- Remove outdated assembler code contrib/masm686 and contrib/asm586 -- Remove old vc7 and vc8 from contrib/vstudio -- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] -- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() -- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] -- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) -- Fix bug in void-returning vsprintf() case in gzwrite.c -- Fix name change from inflate.h in contrib/inflate86/inffas86.c -- Check if temporary file exists before removing in make_vms.com [Zinser] -- Fix make install and uninstall for --static option -- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] -- Update readme.txt in contrib/masmx64 and masmx86 to assemble - -Changes in 1.2.3.9 (21 Feb 2010) -- Expunge gzio.c -- Move as400 build information to old -- Fix updates in contrib/minizip and contrib/vstudio -- Add const to vsnprintf test in configure to avoid warnings [Weigelt] -- Delete zconf.h (made by configure) [Weigelt] -- Change zconf.in.h to zconf.h.in per convention [Weigelt] -- Check for NULL buf in gzgets() -- Return empty string for gzgets() with len == 1 (like fgets()) -- Fix description of gzgets() in zlib.h for end-of-file, NULL return -- Update minizip to 1.1 [Vollant] -- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c -- Note in zlib.h that gzerror() should be used to distinguish from EOF -- Remove use of snprintf() from gzlib.c -- Fix bug in gzseek() -- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] -- Fix zconf.h generation in CMakeLists.txt [Lowman] -- Improve comments in zconf.h where modified by configure - -Changes in 1.2.3.8 (13 Feb 2010) -- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] -- Use z_off64_t in gz_zero() and gz_skip() to match state->skip -- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) -- Revert to Makefile.in from 1.2.3.6 (live with the clutter) -- Fix missing error return in gzflush(), add zlib.h note -- Add *64 functions to zlib.map [Levin] -- Fix signed/unsigned comparison in gz_comp() -- Use SFLAGS when testing shared linking in configure -- Add --64 option to ./configure to use -m64 with gcc -- Fix ./configure --help to correctly name options -- Have make fail if a test fails [Levin] -- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] -- Remove assembler object files from contrib - -Changes in 1.2.3.7 (24 Jan 2010) -- Always gzopen() with O_LARGEFILE if available -- Fix gzdirect() to work immediately after gzopen() or gzdopen() -- Make gzdirect() more precise when the state changes while reading -- Improve zlib.h documentation in many places -- Catch memory allocation failure in gz_open() -- Complete close operation if seek forward in gzclose_w() fails -- Return Z_ERRNO from gzclose_r() if close() fails -- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL -- Return zero for gzwrite() errors to match zlib.h description -- Return -1 on gzputs() error to match zlib.h description -- Add zconf.in.h to allow recovery from configure modification [Weigelt] -- Fix static library permissions in Makefile.in [Weigelt] -- Avoid warnings in configure tests that hide functionality [Weigelt] -- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] -- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] -- Avoid access of uninitialized data for first inflateReset2 call [Gomes] -- Keep object files in subdirectories to reduce the clutter somewhat -- Remove default Makefile and zlibdefs.h, add dummy Makefile -- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ -- Remove zlibdefs.h completely -- modify zconf.h instead - -Changes in 1.2.3.6 (17 Jan 2010) -- Avoid void * arithmetic in gzread.c and gzwrite.c -- Make compilers happier with const char * for gz_error message -- Avoid unused parameter warning in inflate.c -- Avoid signed-unsigned comparison warning in inflate.c -- Indent #pragma's for traditional C -- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() -- Correct email address in configure for system options -- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] -- Update zlib.map [Brown] -- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] -- Apply various fixes to CMakeLists.txt [Lowman] -- Add checks on len in gzread() and gzwrite() -- Add error message for no more room for gzungetc() -- Remove zlib version check in gzwrite() -- Defer compression of gzprintf() result until need to -- Use snprintf() in gzdopen() if available -- Remove USE_MMAP configuration determination (only used by minigzip) -- Remove examples/pigz.c (available separately) -- Update examples/gun.c to 1.6 - -Changes in 1.2.3.5 (8 Jan 2010) -- Add space after #if in zutil.h for some compilers -- Fix relatively harmless bug in deflate_fast() [Exarevsky] -- Fix same problem in deflate_slow() -- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] -- Add deflate_rle() for faster Z_RLE strategy run-length encoding -- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding -- Change name of "write" variable in inffast.c to avoid library collisions -- Fix premature EOF from gzread() in gzio.c [Brown] -- Use zlib header window size if windowBits is 0 in inflateInit2() -- Remove compressBound() call in deflate.c to avoid linking compress.o -- Replace use of errno in gz* with functions, support WinCE [Alves] -- Provide alternative to perror() in minigzip.c for WinCE [Alves] -- Don't use _vsnprintf on later versions of MSVC [Lowman] -- Add CMake build script and input file [Lowman] -- Update contrib/minizip to 1.1 [Svensson, Vollant] -- Moved nintendods directory from contrib to . -- Replace gzio.c with a new set of routines with the same functionality -- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above -- Update contrib/minizip to 1.1b -- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h - -Changes in 1.2.3.4 (21 Dec 2009) -- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility -- Update comments in configure and Makefile.in for default --shared -- Fix test -z's in configure [Marquess] -- Build examplesh and minigzipsh when not testing -- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h -- Import LDFLAGS from the environment in configure -- Fix configure to populate SFLAGS with discovered CFLAGS options -- Adapt make_vms.com to the new Makefile.in [Zinser] -- Add zlib2ansi script for C++ compilation [Marquess] -- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) -- Add AMD64 assembler code for longest match to contrib [Teterin] -- Include options from $SFLAGS when doing $LDSHARED -- Simplify 64-bit file support by introducing z_off64_t type -- Make shared object files in objs directory to work around old Sun cc -- Use only three-part version number for Darwin shared compiles -- Add rc option to ar in Makefile.in for when ./configure not run -- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* -- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile -- Protect against _FILE_OFFSET_BITS being defined when compiling zlib -- Rename Makefile.in targets allstatic to static and allshared to shared -- Fix static and shared Makefile.in targets to be independent -- Correct error return bug in gz_open() by setting state [Brown] -- Put spaces before ;;'s in configure for better sh compatibility -- Add pigz.c (parallel implementation of gzip) to examples/ -- Correct constant in crc32.c to UL [Leventhal] -- Reject negative lengths in crc32_combine() -- Add inflateReset2() function to work like inflateEnd()/inflateInit2() -- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] -- Correct typo in doc/algorithm.txt [Janik] -- Fix bug in adler32_combine() [Zhu] -- Catch missing-end-of-block-code error in all inflates and in puff - Assures that random input to inflate eventually results in an error -- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ -- Update ENOUGH and its usage to reflect discovered bounds -- Fix gzerror() error report on empty input file [Brown] -- Add ush casts in trees.c to avoid pedantic runtime errors -- Fix typo in zlib.h uncompress() description [Reiss] -- Correct inflate() comments with regard to automatic header detection -- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) -- Put new version of gzlog (2.0) in examples with interruption recovery -- Add puff compile option to permit invalid distance-too-far streams -- Add puff TEST command options, ability to read piped input -- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but - _LARGEFILE64_SOURCE not defined -- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart -- Fix deflateSetDictionary() to use all 32K for output consistency -- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) -- Clear bytes after deflate lookahead to avoid use of uninitialized data -- Change a limit in inftrees.c to be more transparent to Coverity Prevent -- Update win32/zlib.def with exported symbols from zlib.h -- Correct spelling errors in zlib.h [Willem, Sobrado] -- Allow Z_BLOCK for deflate() to force a new block -- Allow negative bits in inflatePrime() to delete existing bit buffer -- Add Z_TREES flush option to inflate() to return at end of trees -- Add inflateMark() to return current state information for random access -- Add Makefile for NintendoDS to contrib [Costa] -- Add -w in configure compile tests to avoid spurious warnings [Beucler] -- Fix typos in zlib.h comments for deflateSetDictionary() -- Fix EOF detection in transparent gzread() [Maier] - -Changes in 1.2.3.3 (2 October 2006) -- Make --shared the default for configure, add a --static option -- Add compile option to permit invalid distance-too-far streams -- Add inflateUndermine() function which is required to enable above -- Remove use of "this" variable name for C++ compatibility [Marquess] -- Add testing of shared library in make test, if shared library built -- Use ftello() and fseeko() if available instead of ftell() and fseek() -- Provide two versions of all functions that use the z_off_t type for - binary compatibility -- a normal version and a 64-bit offset version, - per the Large File Support Extension when _LARGEFILE64_SOURCE is - defined; use the 64-bit versions by default when _FILE_OFFSET_BITS - is defined to be 64 -- Add a --uname= option to configure to perhaps help with cross-compiling - -Changes in 1.2.3.2 (3 September 2006) -- Turn off silly Borland warnings [Hay] -- Use off64_t and define _LARGEFILE64_SOURCE when present -- Fix missing dependency on inffixed.h in Makefile.in -- Rig configure --shared to build both shared and static [Teredesai, Truta] -- Remove zconf.in.h and instead create a new zlibdefs.h file -- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] -- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] - -Changes in 1.2.3.1 (16 August 2006) -- Add watcom directory with OpenWatcom make files [Daniel] -- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] -- Update make_vms.com [Zinser] -- Use -fPIC for shared build in configure [Teredesai, Nicholson] -- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] -- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] -- Add some FAQ entries about the contrib directory -- Update the MVS question in the FAQ -- Avoid extraneous reads after EOF in gzio.c [Brown] -- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] -- Add comments to zlib.h about gzerror() usage [Brown] -- Set extra flags in gzip header in gzopen() like deflate() does -- Make configure options more compatible with double-dash conventions - [Weigelt] -- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] -- Fix uninstall target in Makefile.in [Truta] -- Add pkgconfig support [Weigelt] -- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] -- Replace set_data_type() with a more accurate detect_data_type() in - trees.c, according to the txtvsbin.txt document [Truta] -- Swap the order of #include and #include "zlib.h" in - gzio.c, example.c and minigzip.c [Truta] -- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, - Truta] (where?) -- Fix target "clean" from win32/Makefile.bor [Truta] -- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] -- Update zlib www home address in win32/DLL_FAQ.txt [Truta] -- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] -- Enable browse info in the "Debug" and "ASM Debug" configurations in - the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] -- Add pkgconfig support [Weigelt] -- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, - for use in win32/zlib1.rc [Polushin, Rowe, Truta] -- Add a document that explains the new text detection scheme to - doc/txtvsbin.txt [Truta] -- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] -- Move algorithm.txt into doc/ [Truta] -- Synchronize FAQ with website -- Fix compressBound(), was low for some pathological cases [Fearnley] -- Take into account wrapper variations in deflateBound() -- Set examples/zpipe.c input and output to binary mode for Windows -- Update examples/zlib_how.html with new zpipe.c (also web site) -- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems - that gcc became pickier in 4.0) -- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain - un-versioned, the patch adds versioning only for symbols introduced in - zlib-1.2.0 or later. It also declares as local those symbols which are - not designed to be exported." [Levin] -- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure -- Do not initialize global static by default in trees.c, add a response - NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] -- Don't use strerror() in gzio.c under WinCE [Yakimov] -- Don't use errno.h in zutil.h under WinCE [Yakimov] -- Move arguments for AR to its usage to allow replacing ar [Marot] -- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] -- Improve inflateInit() and inflateInit2() documentation -- Fix structure size comment in inflate.h -- Change configure help option from --h* to --help [Santos] - -Changes in 1.2.3 (18 July 2005) -- Apply security vulnerability fixes to contrib/infback9 as well -- Clean up some text files (carriage returns, trailing space) -- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] - -Changes in 1.2.2.4 (11 July 2005) -- Add inflatePrime() function for starting inflation at bit boundary -- Avoid some Visual C warnings in deflate.c -- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit - compile -- Fix some spelling errors in comments [Betts] -- Correct inflateInit2() error return documentation in zlib.h -- Add zran.c example of compressed data random access to examples - directory, shows use of inflatePrime() -- Fix cast for assignments to strm->state in inflate.c and infback.c -- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] -- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] -- Add cast in trees.c t avoid a warning [Oberhumer] -- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] -- Update make_vms.com [Zinser] -- Initialize state->write in inflateReset() since copied in inflate_fast() -- Be more strict on incomplete code sets in inflate_table() and increase - ENOUGH and MAXD -- this repairs a possible security vulnerability for - invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for - discovering the vulnerability and providing test cases. -- Add ia64 support to configure for HP-UX [Smith] -- Add error return to gzread() for format or i/o error [Levin] -- Use malloc.h for OS/2 [Necasek] - -Changes in 1.2.2.3 (27 May 2005) -- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile -- Typecast fread() return values in gzio.c [Vollant] -- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) -- Fix crc check bug in gzread() after gzungetc() [Heiner] -- Add the deflateTune() function to adjust internal compression parameters -- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) -- Remove an incorrect assertion in examples/zpipe.c -- Add C++ wrapper in infback9.h [Donais] -- Fix bug in inflateCopy() when decoding fixed codes -- Note in zlib.h how much deflateSetDictionary() actually uses -- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) -- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] -- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] -- Add gzdirect() function to indicate transparent reads -- Update contrib/minizip [Vollant] -- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] -- Add casts in crc32.c to avoid warnings [Oberhumer] -- Add contrib/masmx64 [Vollant] -- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] - -Changes in 1.2.2.2 (30 December 2004) -- Replace structure assignments in deflate.c and inflate.c with zmemcpy to - avoid implicit memcpy calls (portability for no-library compilation) -- Increase sprintf() buffer size in gzdopen() to allow for large numbers -- Add INFLATE_STRICT to check distances against zlib header -- Improve WinCE errno handling and comments [Chang] -- Remove comment about no gzip header processing in FAQ -- Add Z_FIXED strategy option to deflateInit2() to force fixed trees -- Add updated make_vms.com [Coghlan], update README -- Create a new "examples" directory, move gzappend.c there, add zpipe.c, - fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. -- Add FAQ entry and comments in deflate.c on uninitialized memory access -- Add Solaris 9 make options in configure [Gilbert] -- Allow strerror() usage in gzio.c for STDC -- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] -- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] -- Use z_off_t for adler32_combine() and crc32_combine() lengths -- Make adler32() much faster for small len -- Use OS_CODE in deflate() default gzip header - -Changes in 1.2.2.1 (31 October 2004) -- Allow inflateSetDictionary() call for raw inflate -- Fix inflate header crc check bug for file names and comments -- Add deflateSetHeader() and gz_header structure for custom gzip headers -- Add inflateGetheader() to retrieve gzip headers -- Add crc32_combine() and adler32_combine() functions -- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list -- Use zstreamp consistently in zlib.h (inflate_back functions) -- Remove GUNZIP condition from definition of inflate_mode in inflate.h - and in contrib/inflate86/inffast.S [Truta, Anderson] -- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] -- Update projects/README.projects and projects/visualc6 [Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] -- Deprecate Z_ASCII; use Z_TEXT instead [Truta] -- Use a new algorithm for setting strm->data_type in trees.c [Truta] -- Do not define an exit() prototype in zutil.c unless DEBUG defined -- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] -- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() -- Fix Darwin build version identification [Peterson] - -Changes in 1.2.2 (3 October 2004) -- Update zlib.h comments on gzip in-memory processing -- Set adler to 1 in inflateReset() to support Java test suite [Walles] -- Add contrib/dotzlib [Ravn] -- Update win32/DLL_FAQ.txt [Truta] -- Update contrib/minizip [Vollant] -- Move contrib/visual-basic.txt to old/ [Truta] -- Fix assembler builds in projects/visualc6/ [Truta] - -Changes in 1.2.1.2 (9 September 2004) -- Update INDEX file -- Fix trees.c to update strm->data_type (no one ever noticed!) -- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] -- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) -- Add limited multitasking protection to DYNAMIC_CRC_TABLE -- Add NO_vsnprintf for VMS in zutil.h [Mozilla] -- Don't declare strerror() under VMS [Mozilla] -- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize -- Update contrib/ada [Anisimkov] -- Update contrib/minizip [Vollant] -- Fix configure to not hardcode directories for Darwin [Peterson] -- Fix gzio.c to not return error on empty files [Brown] -- Fix indentation; update version in contrib/delphi/ZLib.pas and - contrib/pascal/zlibpas.pas [Truta] -- Update mkasm.bat in contrib/masmx86 [Truta] -- Update contrib/untgz [Truta] -- Add projects/README.projects [Truta] -- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] -- Remove an unnecessary assignment to curr in inftrees.c [Truta] -- Add OS/2 to exe builds in configure [Poltorak] -- Remove err dummy parameter in zlib.h [Kientzle] - -Changes in 1.2.1.1 (9 January 2004) -- Update email address in README -- Several FAQ updates -- Fix a big fat bug in inftrees.c that prevented decoding valid - dynamic blocks with only literals and no distance codes -- - Thanks to "Hot Emu" for the bug report and sample file -- Add a note to puff.c on no distance codes case. - -Changes in 1.2.1 (17 November 2003) -- Remove a tab in contrib/gzappend/gzappend.c -- Update some interfaces in contrib for new zlib functions -- Update zlib version number in some contrib entries -- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] -- Support shared libraries on Hurd and KFreeBSD [Brown] -- Fix error in NO_DIVIDE option of adler32.c - -Changes in 1.2.0.8 (4 November 2003) -- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas -- Add experimental NO_DIVIDE #define in adler32.c - - Possibly faster on some processors (let me know if it is) -- Correct Z_BLOCK to not return on first inflate call if no wrap -- Fix strm->data_type on inflate() return to correctly indicate EOB -- Add deflatePrime() function for appending in the middle of a byte -- Add contrib/gzappend for an example of appending to a stream -- Update win32/DLL_FAQ.txt [Truta] -- Delete Turbo C comment in README [Truta] -- Improve some indentation in zconf.h [Truta] -- Fix infinite loop on bad input in configure script [Church] -- Fix gzeof() for concatenated gzip files [Johnson] -- Add example to contrib/visual-basic.txt [Michael B.] -- Add -p to mkdir's in Makefile.in [vda] -- Fix configure to properly detect presence or lack of printf functions -- Add AS400 support [Monnerat] -- Add a little Cygwin support [Wilson] - -Changes in 1.2.0.7 (21 September 2003) -- Correct some debug formats in contrib/infback9 -- Cast a type in a debug statement in trees.c -- Change search and replace delimiter in configure from % to # [Beebe] -- Update contrib/untgz to 0.2 with various fixes [Truta] -- Add build support for Amiga [Nikl] -- Remove some directories in old that have been updated to 1.2 -- Add dylib building for Mac OS X in configure and Makefile.in -- Remove old distribution stuff from Makefile -- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X -- Update links in README - -Changes in 1.2.0.6 (13 September 2003) -- Minor FAQ updates -- Update contrib/minizip to 1.00 [Vollant] -- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] -- Update POSTINC comment for 68060 [Nikl] -- Add contrib/infback9 with deflate64 decoding (unsupported) -- For MVS define NO_vsnprintf and undefine FAR [van Burik] -- Add pragma for fdopen on MVS [van Burik] - -Changes in 1.2.0.5 (8 September 2003) -- Add OF to inflateBackEnd() declaration in zlib.h -- Remember start when using gzdopen in the middle of a file -- Use internal off_t counters in gz* functions to properly handle seeks -- Perform more rigorous check for distance-too-far in inffast.c -- Add Z_BLOCK flush option to return from inflate at block boundary -- Set strm->data_type on return from inflate - - Indicate bits unused, if at block boundary, and if in last block -- Replace size_t with ptrdiff_t in crc32.c, and check for correct size -- Add condition so old NO_DEFLATE define still works for compatibility -- FAQ update regarding the Windows DLL [Truta] -- INDEX update: add qnx entry, remove aix entry [Truta] -- Install zlib.3 into mandir [Wilson] -- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] -- Adapt the zlib interface to the new DLL convention guidelines [Truta] -- Introduce ZLIB_WINAPI macro to allow the export of functions using - the WINAPI calling convention, for Visual Basic [Vollant, Truta] -- Update msdos and win32 scripts and makefiles [Truta] -- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] -- Add contrib/ada [Anisimkov] -- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] -- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] -- Add contrib/masm686 [Truta] -- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm - [Truta, Vollant] -- Update contrib/delphi; rename to contrib/pascal; add example [Truta] -- Remove contrib/delphi2; add a new contrib/delphi [Truta] -- Avoid inclusion of the nonstandard in contrib/iostream, - and fix some method prototypes [Truta] -- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip - [Truta] -- Avoid the use of backslash (\) in contrib/minizip [Vollant] -- Fix file time handling in contrib/untgz; update makefiles [Truta] -- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines - [Vollant] -- Remove contrib/vstudio/vc15_16 [Vollant] -- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] -- Update README.contrib [Truta] -- Invert the assignment order of match_head and s->prev[...] in - INSERT_STRING [Truta] -- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings - [Truta] -- Compare function pointers with 0, not with NULL or Z_NULL [Truta] -- Fix prototype of syncsearch in inflate.c [Truta] -- Introduce ASMINF macro to be enabled when using an ASM implementation - of inflate_fast [Truta] -- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] -- Modify test_gzio in example.c to take a single file name as a - parameter [Truta] -- Exit the example.c program if gzopen fails [Truta] -- Add type casts around strlen in example.c [Truta] -- Remove casting to sizeof in minigzip.c; give a proper type - to the variable compared with SUFFIX_LEN [Truta] -- Update definitions of STDC and STDC99 in zconf.h [Truta] -- Synchronize zconf.h with the new Windows DLL interface [Truta] -- Use SYS16BIT instead of __32BIT__ to distinguish between - 16- and 32-bit platforms [Truta] -- Use far memory allocators in small 16-bit memory models for - Turbo C [Truta] -- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in - zlibCompileFlags [Truta] -- Cygwin has vsnprintf [Wilson] -- In Windows16, OS_CODE is 0, as in MSDOS [Truta] -- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] - -Changes in 1.2.0.4 (10 August 2003) -- Minor FAQ updates -- Be more strict when checking inflateInit2's windowBits parameter -- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well -- Add gzip wrapper option to deflateInit2 using windowBits -- Add updated QNX rule in configure and qnx directory [Bonnefoy] -- Make inflate distance-too-far checks more rigorous -- Clean up FAR usage in inflate -- Add casting to sizeof() in gzio.c and minigzip.c - -Changes in 1.2.0.3 (19 July 2003) -- Fix silly error in gzungetc() implementation [Vollant] -- Update contrib/minizip and contrib/vstudio [Vollant] -- Fix printf format in example.c -- Correct cdecl support in zconf.in.h [Anisimkov] -- Minor FAQ updates - -Changes in 1.2.0.2 (13 July 2003) -- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons -- Attempt to avoid warnings in crc32.c for pointer-int conversion -- Add AIX to configure, remove aix directory [Bakker] -- Add some casts to minigzip.c -- Improve checking after insecure sprintf() or vsprintf() calls -- Remove #elif's from crc32.c -- Change leave label to inf_leave in inflate.c and infback.c to avoid - library conflicts -- Remove inflate gzip decoding by default--only enable gzip decoding by - special request for stricter backward compatibility -- Add zlibCompileFlags() function to return compilation information -- More typecasting in deflate.c to avoid warnings -- Remove leading underscore from _Capital #defines [Truta] -- Fix configure to link shared library when testing -- Add some Windows CE target adjustments [Mai] -- Remove #define ZLIB_DLL in zconf.h [Vollant] -- Add zlib.3 [Rodgers] -- Update RFC URL in deflate.c and algorithm.txt [Mai] -- Add zlib_dll_FAQ.txt to contrib [Truta] -- Add UL to some constants [Truta] -- Update minizip and vstudio [Vollant] -- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h -- Expand use of NO_DUMMY_DECL to avoid all dummy structures -- Added iostream3 to contrib [Schwardt] -- Replace rewind() with fseek() for WinCE [Truta] -- Improve setting of zlib format compression level flags - - Report 0 for huffman and rle strategies and for level == 0 or 1 - - Report 2 only for level == 6 -- Only deal with 64K limit when necessary at compile time [Truta] -- Allow TOO_FAR check to be turned off at compile time [Truta] -- Add gzclearerr() function [Souza] -- Add gzungetc() function - -Changes in 1.2.0.1 (17 March 2003) -- Add Z_RLE strategy for run-length encoding [Truta] - - When Z_RLE requested, restrict matches to distance one - - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE -- Correct FASTEST compilation to allow level == 0 -- Clean up what gets compiled for FASTEST -- Incorporate changes to zconf.in.h [Vollant] - - Refine detection of Turbo C need for dummy returns - - Refine ZLIB_DLL compilation - - Include additional header file on VMS for off_t typedef -- Try to use _vsnprintf where it supplants vsprintf [Vollant] -- Add some casts in inffast.c -- Enchance comments in zlib.h on what happens if gzprintf() tries to - write more than 4095 bytes before compression -- Remove unused state from inflateBackEnd() -- Remove exit(0) from minigzip.c, example.c -- Get rid of all those darn tabs -- Add "check" target to Makefile.in that does the same thing as "test" -- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in -- Update contrib/inflate86 [Anderson] -- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] -- Add msdos and win32 directories with makefiles [Truta] -- More additions and improvements to the FAQ - -Changes in 1.2.0 (9 March 2003) -- New and improved inflate code - - About 20% faster - - Does not allocate 32K window unless and until needed - - Automatically detects and decompresses gzip streams - - Raw inflate no longer needs an extra dummy byte at end - - Added inflateBack functions using a callback interface--even faster - than inflate, useful for file utilities (gzip, zip) - - Added inflateCopy() function to record state for random access on - externally generated deflate streams (e.g. in gzip files) - - More readable code (I hope) -- New and improved crc32() - - About 50% faster, thanks to suggestions from Rodney Brown -- Add deflateBound() and compressBound() functions -- Fix memory leak in deflateInit2() -- Permit setting dictionary for raw deflate (for parallel deflate) -- Fix const declaration for gzwrite() -- Check for some malloc() failures in gzio.c -- Fix bug in gzopen() on single-byte file 0x1f -- Fix bug in gzread() on concatenated file with 0x1f at end of buffer - and next buffer doesn't start with 0x8b -- Fix uncompress() to return Z_DATA_ERROR on truncated input -- Free memory at end of example.c -- Remove MAX #define in trees.c (conflicted with some libraries) -- Fix static const's in deflate.c, gzio.c, and zutil.[ch] -- Declare malloc() and free() in gzio.c if STDC not defined -- Use malloc() instead of calloc() in zutil.c if int big enough -- Define STDC for AIX -- Add aix/ with approach for compiling shared library on AIX -- Add HP-UX support for shared libraries in configure -- Add OpenUNIX support for shared libraries in configure -- Use $cc instead of gcc to build shared library -- Make prefix directory if needed when installing -- Correct Macintosh avoidance of typedef Byte in zconf.h -- Correct Turbo C memory allocation when under Linux -- Use libz.a instead of -lz in Makefile (assure use of compiled library) -- Update configure to check for snprintf or vsnprintf functions and their - return value, warn during make if using an insecure function -- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that - is lost when library is used--resolution is to build new zconf.h -- Documentation improvements (in zlib.h): - - Document raw deflate and inflate - - Update RFCs URL - - Point out that zlib and gzip formats are different - - Note that Z_BUF_ERROR is not fatal - - Document string limit for gzprintf() and possible buffer overflow - - Note requirement on avail_out when flushing - - Note permitted values of flush parameter of inflate() -- Add some FAQs (and even answers) to the FAQ -- Add contrib/inflate86/ for x86 faster inflate -- Add contrib/blast/ for PKWare Data Compression Library decompression -- Add contrib/puff/ simple inflate for deflate format description - -Changes in 1.1.4 (11 March 2002) -- ZFREE was repeated on same allocation on some error conditions. - This creates a security problem described in - http://www.zlib.org/advisory-2002-03-11.txt -- Returned incorrect error (Z_MEM_ERROR) on some invalid data -- Avoid accesses before window for invalid distances with inflate window - less than 32K. -- force windowBits > 8 to avoid a bug in the encoder for a window size - of 256 bytes. (A complete fix will be available in 1.1.5). - -Changes in 1.1.3 (9 July 1998) -- fix "an inflate input buffer bug that shows up on rare but persistent - occasions" (Mark) -- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) -- fix gzseek(..., SEEK_SET) in write mode -- fix crc check after a gzeek (Frank Faubert) -- fix miniunzip when the last entry in a zip file is itself a zip file - (J Lillge) -- add contrib/asm586 and contrib/asm686 (Brian Raiter) - See http://www.muppetlabs.com/~breadbox/software/assembly.html -- add support for Delphi 3 in contrib/delphi (Bob Dellaca) -- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) -- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) -- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) -- added a FAQ file - -- Support gzdopen on Mac with Metrowerks (Jason Linhart) -- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) -- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) -- avoid some warnings with Borland C (Tom Tanner) -- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) -- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) -- allow several arguments to configure (Tim Mooney, Frodo Looijaard) -- use libdir and includedir in Makefile.in (Tim Mooney) -- support shared libraries on OSF1 V4 (Tim Mooney) -- remove so_locations in "make clean" (Tim Mooney) -- fix maketree.c compilation error (Glenn, Mark) -- Python interface to zlib now in Python 1.5 (Jeremy Hylton) -- new Makefile.riscos (Rich Walker) -- initialize static descriptors in trees.c for embedded targets (Nick Smith) -- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) -- add the OS/2 files in Makefile.in too (Andrew Zabolotny) -- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) -- fix maketree.c to allow clean compilation of inffixed.h (Mark) -- fix parameter check in deflateCopy (Gunther Nikl) -- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) -- Many portability patches by Christian Spieler: - . zutil.c, zutil.h: added "const" for zmem* - . Make_vms.com: fixed some typos - . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists - . msdos/Makefile.msc: remove "default rtl link library" info from obj files - . msdos/Makefile.*: use model-dependent name for the built zlib library - . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: - new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) -- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) -- replace __far with _far for better portability (Christian Spieler, Tom Lane) -- fix test for errno.h in configure (Tim Newsham) - -Changes in 1.1.2 (19 March 98) -- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) - See http://www.winimage.com/zLibDll/unzip.html -- preinitialize the inflate tables for fixed codes, to make the code - completely thread safe (Mark) -- some simplifications and slight speed-up to the inflate code (Mark) -- fix gzeof on non-compressed files (Allan Schrum) -- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) -- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) -- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) -- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) -- do not wrap extern "C" around system includes (Tom Lane) -- mention zlib binding for TCL in README (Andreas Kupries) -- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) -- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) -- allow "configure --prefix $HOME" (Tim Mooney) -- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) -- move Makefile.sas to amiga/Makefile.sas - -Changes in 1.1.1 (27 Feb 98) -- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) -- remove block truncation heuristic which had very marginal effect for zlib - (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the - compression ratio on some files. This also allows inlining _tr_tally for - matches in deflate_slow. -- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) - -Changes in 1.1.0 (24 Feb 98) -- do not return STREAM_END prematurely in inflate (John Bowler) -- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) -- compile with -DFASTEST to get compression code optimized for speed only -- in minigzip, try mmap'ing the input file first (Miguel Albrecht) -- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain - on Sun but significant on HP) - -- add a pointer to experimental unzip library in README (Gilles Vollant) -- initialize variable gcc in configure (Chris Herborth) - -Changes in 1.0.9 (17 Feb 1998) -- added gzputs and gzgets functions -- do not clear eof flag in gzseek (Mark Diekhans) -- fix gzseek for files in transparent mode (Mark Diekhans) -- do not assume that vsprintf returns the number of bytes written (Jens Krinke) -- replace EXPORT with ZEXPORT to avoid conflict with other programs -- added compress2 in zconf.h, zlib.def, zlib.dnt -- new asm code from Gilles Vollant in contrib/asm386 -- simplify the inflate code (Mark): - . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() - . ZALLOC the length list in inflate_trees_fixed() instead of using stack - . ZALLOC the value area for huft_build() instead of using stack - . Simplify Z_FINISH check in inflate() - -- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 -- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) -- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with - the declaration of FAR (Gilles VOllant) -- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) -- read_buf buf parameter of type Bytef* instead of charf* -- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) -- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) -- fix check for presence of directories in "make install" (Ian Willis) - -Changes in 1.0.8 (27 Jan 1998) -- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) -- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) -- added compress2() to allow setting the compression level -- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) -- use constant arrays for the static trees in trees.c instead of computing - them at run time (thanks to Ken Raeburn for this suggestion). To create - trees.h, compile with GEN_TREES_H and run "make test". -- check return code of example in "make test" and display result -- pass minigzip command line options to file_compress -- simplifying code of inflateSync to avoid gcc 2.8 bug - -- support CC="gcc -Wall" in configure -s (QingLong) -- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) -- fix test for shared library support to avoid compiler warnings -- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) -- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) -- do not use fdopen for Metrowerks on Mac (Brad Pettit)) -- add checks for gzputc and gzputc in example.c -- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) -- use const for the CRC table (Ken Raeburn) -- fixed "make uninstall" for shared libraries -- use Tracev instead of Trace in infblock.c -- in example.c use correct compressed length for test_sync -- suppress +vnocompatwarnings in configure for HPUX (not always supported) - -Changes in 1.0.7 (20 Jan 1998) -- fix gzseek which was broken in write mode -- return error for gzseek to negative absolute position -- fix configure for Linux (Chun-Chung Chen) -- increase stack space for MSC (Tim Wegner) -- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) -- define EXPORTVA for gzprintf (Gilles Vollant) -- added man page zlib.3 (Rick Rodgers) -- for contrib/untgz, fix makedir() and improve Makefile - -- check gzseek in write mode in example.c -- allocate extra buffer for seeks only if gzseek is actually called -- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) -- add inflateSyncPoint in zconf.h -- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def - -Changes in 1.0.6 (19 Jan 1998) -- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and - gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) -- Fix a deflate bug occurring only with compression level 0 (thanks to - Andy Buckler for finding this one). -- In minigzip, pass transparently also the first byte for .Z files. -- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() -- check Z_FINISH in inflate (thanks to Marc Schluper) -- Implement deflateCopy (thanks to Adam Costello) -- make static libraries by default in configure, add --shared option. -- move MSDOS or Windows specific files to directory msdos -- suppress the notion of partial flush to simplify the interface - (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) -- suppress history buffer provided by application to simplify the interface - (this feature was not implemented anyway in 1.0.4) -- next_in and avail_in must be initialized before calling inflateInit or - inflateInit2 -- add EXPORT in all exported functions (for Windows DLL) -- added Makefile.nt (thanks to Stephen Williams) -- added the unsupported "contrib" directory: - contrib/asm386/ by Gilles Vollant - 386 asm code replacing longest_match(). - contrib/iostream/ by Kevin Ruland - A C++ I/O streams interface to the zlib gz* functions - contrib/iostream2/ by Tyge Løvset - Another C++ I/O streams interface - contrib/untgz/ by "Pedro A. Aranda Guti\irrez" - A very simple tar.gz file extractor using zlib - contrib/visual-basic.txt by Carlos Rios - How to use compress(), uncompress() and the gz* functions from VB. -- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression - level) in minigzip (thanks to Tom Lane) - -- use const for rommable constants in deflate -- added test for gzseek and gztell in example.c -- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) -- add undocumented function zError to convert error code to string - (for Tim Smithers) -- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. -- Use default memcpy for Symantec MSDOS compiler. -- Add EXPORT keyword for check_func (needed for Windows DLL) -- add current directory to LD_LIBRARY_PATH for "make test" -- create also a link for libz.so.1 -- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) -- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) -- added -soname for Linux in configure (Chun-Chung Chen, -- assign numbers to the exported functions in zlib.def (for Windows DLL) -- add advice in zlib.h for best usage of deflateSetDictionary -- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) -- allow compilation with ANSI keywords only enabled for TurboC in large model -- avoid "versionString"[0] (Borland bug) -- add NEED_DUMMY_RETURN for Borland -- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). -- allow compilation with CC -- defined STDC for OS/2 (David Charlap) -- limit external names to 8 chars for MVS (Thomas Lund) -- in minigzip.c, use static buffers only for 16-bit systems -- fix suffix check for "minigzip -d foo.gz" -- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) -- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) -- added makelcc.bat for lcc-win32 (Tom St Denis) -- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. -- check for unistd.h in configure (for off_t) -- remove useless check parameter in inflate_blocks_free -- avoid useless assignment of s->check to itself in inflate_blocks_new -- do not flush twice in gzclose (thanks to Ken Raeburn) -- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h -- use NO_ERRNO_H instead of enumeration of operating systems with errno.h -- work around buggy fclose on pipes for HP/UX -- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) -- fix configure if CC is already equal to gcc - -Changes in 1.0.5 (3 Jan 98) -- Fix inflate to terminate gracefully when fed corrupted or invalid data -- Use const for rommable constants in inflate -- Eliminate memory leaks on error conditions in inflate -- Removed some vestigial code in inflate -- Update web address in README - -Changes in 1.0.4 (24 Jul 96) -- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF - bit, so the decompressor could decompress all the correct data but went - on to attempt decompressing extra garbage data. This affected minigzip too. -- zlibVersion and gzerror return const char* (needed for DLL) -- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) -- use z_error only for DEBUG (avoid problem with DLLs) - -Changes in 1.0.3 (2 Jul 96) -- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS - small and medium models; this makes the library incompatible with previous - versions for these models. (No effect in large model or on other systems.) -- return OK instead of BUF_ERROR if previous deflate call returned with - avail_out as zero but there is nothing to do -- added memcmp for non STDC compilers -- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) -- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) -- better check for 16-bit mode MSC (avoids problem with Symantec) - -Changes in 1.0.2 (23 May 96) -- added Windows DLL support -- added a function zlibVersion (for the DLL support) -- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) -- Bytef is define's instead of typedef'd only for Borland C -- avoid reading uninitialized memory in example.c -- mention in README that the zlib format is now RFC1950 -- updated Makefile.dj2 -- added algorithm.doc - -Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] -- fix array overlay in deflate.c which sometimes caused bad compressed data -- fix inflate bug with empty stored block -- fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generate bad compressed data. -- Bytef is define'd instead of typedef'ed (work around Borland bug) -- added an INDEX file -- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), - Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) -- speed up adler32 for modern machines without auto-increment -- added -ansi for IRIX in configure -- static_init_done in trees.c is an int -- define unlink as delete for VMS -- fix configure for QNX -- add configure branch for SCO and HPUX -- avoid many warnings (unused variables, dead assignments, etc...) -- no fdopen for BeOS -- fix the Watcom fix for 32 bit mode (define FAR as empty) -- removed redefinition of Byte for MKWERKS -- work around an MWKERKS bug (incorrect merge of all .h files) - -Changes in 0.99 (27 Jan 96) -- allow preset dictionary shared between compressor and decompressor -- allow compression level 0 (no compression) -- add deflateParams in zlib.h: allow dynamic change of compression level - and compression strategy. -- test large buffers and deflateParams in example.c -- add optional "configure" to build zlib as a shared library -- suppress Makefile.qnx, use configure instead -- fixed deflate for 64-bit systems (detected on Cray) -- fixed inflate_blocks for 64-bit systems (detected on Alpha) -- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) -- always return Z_BUF_ERROR when deflate() has nothing to do -- deflateInit and inflateInit are now macros to allow version checking -- prefix all global functions and types with z_ with -DZ_PREFIX -- make falloc completely reentrant (inftrees.c) -- fixed very unlikely race condition in ct_static_init -- free in reverse order of allocation to help memory manager -- use zlib-1.0/* instead of zlib/* inside the tar.gz -- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith - -Wconversion -Wstrict-prototypes -Wmissing-prototypes" -- allow gzread on concatenated .gz files -- deflateEnd now returns Z_DATA_ERROR if it was premature -- deflate is finally (?) fully deterministic (no matches beyond end of input) -- Document Z_SYNC_FLUSH -- add uninstall in Makefile -- Check for __cpluplus in zlib.h -- Better test in ct_align for partial flush -- avoid harmless warnings for Borland C++ -- initialize hash_head in deflate.c -- avoid warning on fdopen (gzio.c) for HP cc -Aa -- include stdlib.h for STDC compilers -- include errno.h for Cray -- ignore error if ranlib doesn't exist -- call ranlib twice for NeXTSTEP -- use exec_prefix instead of prefix for libz.a -- renamed ct_* as _tr_* to avoid conflict with applications -- clear z->msg in inflateInit2 before any error return -- initialize opaque in example.c, gzio.c, deflate.c and inflate.c -- fixed typo in zconf.h (_GNUC__ => __GNUC__) -- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) -- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) -- in fcalloc, normalize pointer if size > 65520 bytes -- don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... -- use Z_BINARY instead of BINARY -- document that gzclose after gzdopen will close the file -- allow "a" as mode in gzopen. -- fix error checking in gzread -- allow skipping .gz extra-field on pipes -- added reference to Perl interface in README -- put the crc table in FAR data (I dislike more and more the medium model :) -- added get_crc_table -- added a dimension to all arrays (Borland C can't count). -- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast -- guard against multiple inclusion of *.h (for precompiled header on Mac) -- Watcom C pretends to be Microsoft C small model even in 32 bit mode. -- don't use unsized arrays to avoid silly warnings by Visual C++: - warning C4746: 'inflate_mask' : unsized array treated as '__far' - (what's wrong with far data in far model?). -- define enum out of inflate_blocks_state to allow compilation with C++ - -Changes in 0.95 (16 Aug 95) -- fix MSDOS small and medium model (now easier to adapt to any compiler) -- inlined send_bits -- fix the final (:-) bug for deflate with flush (output was correct but - not completely flushed in rare occasions). -- default window size is same for compression and decompression - (it's now sufficient to set MAX_WBITS in zconf.h). -- voidp -> voidpf and voidnp -> voidp (for consistency with other - typedefs and because voidnp was not near in large model). - -Changes in 0.94 (13 Aug 95) -- support MSDOS medium model -- fix deflate with flush (could sometimes generate bad output) -- fix deflateReset (zlib header was incorrectly suppressed) -- added support for VMS -- allow a compression level in gzopen() -- gzflush now calls fflush -- For deflate with flush, flush even if no more input is provided. -- rename libgz.a as libz.a -- avoid complex expression in infcodes.c triggering Turbo C bug -- work around a problem with gcc on Alpha (in INSERT_STRING) -- don't use inline functions (problem with some gcc versions) -- allow renaming of Byte, uInt, etc... with #define. -- avoid warning about (unused) pointer before start of array in deflate.c -- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c -- avoid reserved word 'new' in trees.c - -Changes in 0.93 (25 June 95) -- temporarily disable inline functions -- make deflate deterministic -- give enough lookahead for PARTIAL_FLUSH -- Set binary mode for stdin/stdout in minigzip.c for OS/2 -- don't even use signed char in inflate (not portable enough) -- fix inflate memory leak for segmented architectures - -Changes in 0.92 (3 May 95) -- don't assume that char is signed (problem on SGI) -- Clear bit buffer when starting a stored block -- no memcpy on Pyramid -- suppressed inftest.c -- optimized fill_window, put longest_match inline for gcc -- optimized inflate on stored blocks. -- untabify all sources to simplify patches - -Changes in 0.91 (2 May 95) -- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h -- Document the memory requirements in zconf.h -- added "make install" -- fix sync search logic in inflateSync -- deflate(Z_FULL_FLUSH) now works even if output buffer too short -- after inflateSync, don't scare people with just "lo world" -- added support for DJGPP - -Changes in 0.9 (1 May 95) -- don't assume that zalloc clears the allocated memory (the TurboC bug - was Mark's bug after all :) -- let again gzread copy uncompressed data unchanged (was working in 0.71) -- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented -- added a test of inflateSync in example.c -- moved MAX_WBITS to zconf.h because users might want to change that. -- document explicitly that zalloc(64K) on MSDOS must return a normalized - pointer (zero offset) -- added Makefiles for Microsoft C, Turbo C, Borland C++ -- faster crc32() - -Changes in 0.8 (29 April 95) -- added fast inflate (inffast.c) -- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this - is incompatible with previous versions of zlib which returned Z_OK. -- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) - (actually that was not a compiler bug, see 0.81 above) -- gzread no longer reads one extra byte in certain cases -- In gzio destroy(), don't reference a freed structure -- avoid many warnings for MSDOS -- avoid the ERROR symbol which is used by MS Windows - -Changes in 0.71 (14 April 95) -- Fixed more MSDOS compilation problems :( There is still a bug with - TurboC large model. - -Changes in 0.7 (14 April 95) -- Added full inflate support. -- Simplified the crc32() interface. The pre- and post-conditioning - (one's complement) is now done inside crc32(). WARNING: this is - incompatible with previous versions; see zlib.h for the new usage. - -Changes in 0.61 (12 April 95) -- workaround for a bug in TurboC. example and minigzip now work on MSDOS. - -Changes in 0.6 (11 April 95) -- added minigzip.c -- added gzdopen to reopen a file descriptor as gzFile -- added transparent reading of non-gziped files in gzread. -- fixed bug in gzread (don't read crc as data) -- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). -- don't allocate big arrays in the stack (for MSDOS) -- fix some MSDOS compilation problems - -Changes in 0.5: -- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but - not yet Z_FULL_FLUSH. -- support decompression but only in a single step (forced Z_FINISH) -- added opaque object for zalloc and zfree. -- added deflateReset and inflateReset -- added a variable zlib_version for consistency checking. -- renamed the 'filter' parameter of deflateInit2 as 'strategy'. - Added Z_FILTERED and Z_HUFFMAN_ONLY constants. - -Changes in 0.4: -- avoid "zip" everywhere, use zlib instead of ziplib. -- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush - if compression method == 8. -- added adler32 and crc32 -- renamed deflateOptions as deflateInit2, call one or the other but not both -- added the method parameter for deflateInit2. -- added inflateInit2 -- simplied considerably deflateInit and inflateInit by not supporting - user-provided history buffer. This is supported only in deflateInit2 - and inflateInit2. - -Changes in 0.3: -- prefix all macro names with Z_ -- use Z_FINISH instead of deflateEnd to finish compression. -- added Z_HUFFMAN_ONLY -- added gzerror() diff --git a/ModelicaExternalC/C-Sources/zlib/FAQ b/ModelicaExternalC/C-Sources/zlib/FAQ deleted file mode 100644 index 99b7cf92e..000000000 --- a/ModelicaExternalC/C-Sources/zlib/FAQ +++ /dev/null @@ -1,368 +0,0 @@ - - Frequently Asked Questions about zlib - - -If your question is not there, please check the zlib home page -http://zlib.net/ which may have more recent information. -The lastest zlib FAQ is at http://zlib.net/zlib_faq.html - - - 1. Is zlib Y2K-compliant? - - Yes. zlib doesn't handle dates. - - 2. Where can I get a Windows DLL version? - - The zlib sources can be compiled without change to produce a DLL. See the - file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the - precompiled DLL are found in the zlib web site at http://zlib.net/ . - - 3. Where can I get a Visual Basic interface to zlib? - - See - * http://marknelson.us/1997/01/01/zlib-engine/ - * win32/DLL_FAQ.txt in the zlib distribution - - 4. compress() returns Z_BUF_ERROR. - - Make sure that before the call of compress(), the length of the compressed - buffer is equal to the available size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference - ("as any"), not by value ("as long"). - - 5. deflate() or inflate() returns Z_BUF_ERROR. - - Before making the call, make sure that avail_in and avail_out are not zero. - When setting the parameter flush equal to Z_FINISH, also make sure that - avail_out is big enough to allow processing all pending input. Note that a - Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be - made with more input or output space. A Z_BUF_ERROR may in fact be - unavoidable depending on how the functions are used, since it is not - possible to tell whether or not there is more output pending when - strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a - heavily annotated example. - - 6. Where's the zlib documentation (man pages, etc.)? - - It's in zlib.h . Examples of zlib usage are in the files test/example.c - and test/minigzip.c, with more in examples/ . - - 7. Why don't you use GNU autoconf or libtool or ...? - - Because we would like to keep zlib as a very small and simple package. - zlib is rather portable and doesn't need much configuration. - - 8. I found a bug in zlib. - - Most of the time, such problems are due to an incorrect usage of zlib. - Please try to reproduce the problem with a small program and send the - corresponding source to us at zlib@gzip.org . Do not send multi-megabyte - data files without prior agreement. - - 9. Why do I get "undefined reference to gzputc"? - - If "make test" produces something like - - example.o(.text+0x154): undefined reference to `gzputc' - - check that you don't have old files libz.* in /usr/lib, /usr/local/lib or - /usr/X11R6/lib. Remove any old versions, then do "make install". - -10. I need a Delphi interface to zlib. - - See the contrib/delphi directory in the zlib distribution. - -11. Can zlib handle .zip archives? - - Not by itself, no. See the directory contrib/minizip in the zlib - distribution. - -12. Can zlib handle .Z files? - - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt - the code of uncompress on your own. - -13. How can I make a Unix shared library? - - By default a shared (and a static) library is built for Unix. So: - - make distclean - ./configure - make - -14. How do I install a shared zlib library on Unix? - - After the above, then: - - make install - - However, many flavors of Unix come with a shared zlib already installed. - Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include , it's there. The -lz option will probably link to - it. You can check the version at the top of zlib.h or with the - ZLIB_VERSION symbol defined in zlib.h . - -15. I have a question about OttoPDF. - - We are not the authors of OttoPDF. The real author is on the OttoPDF web - site: Joel Hainley, jhainley@myndkryme.com. - -16. Can zlib decode Flate data in an Adobe PDF file? - - Yes. See http://www.pdflib.com/ . To modify PDF forms, see - http://sourceforge.net/projects/acroformtool/ . - -17. Why am I getting this "register_frame_info not found" error on Solaris? - - After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib - generates an error such as: - - ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: - symbol __register_frame_info: referenced symbol not found - - The symbol __register_frame_info is not part of zlib, it is generated by - the C compiler (cc or gcc). You must recompile applications using zlib - which have this problem. This problem is specific to Solaris. See - http://www.sunfreeware.com for Solaris versions of zlib and applications - using zlib. - -18. Why does gzip give an error on a file I make with compress/deflate? - - The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip formats - use the same compressed data format internally, but have different headers - and trailers around the compressed data. - -19. Ok, so why are there two different formats? - - The gzip format was designed to retain the directory information about a - single file, such as the name and last modification date. The zlib format - on the other hand was designed for in-memory and communication channel - applications, and has a much more compact header and trailer and uses a - faster integrity check than gzip. - -20. Well that's nice, but how do I make a gzip file in memory? - - You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode the - gzip format using inflateInit2(). Read zlib.h for more details. - -21. Is zlib thread-safe? - - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* - functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's *Init* functions - allow for the application to provide custom memory allocation routines. - - Of course, you should only operate on any given zlib or gzip stream from a - single thread at a time. - -22. Can I use zlib in my commercial application? - - Yes. Please read the license in zlib.h. - -23. Is zlib under the GNU license? - - No. Please read the license in zlib.h. - -24. The license says that altered source versions must be "plainly marked". So - what exactly do I need to do to meet that requirement? - - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In - particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers - x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering - is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also - update the version strings in deflate.c and inftrees.c. - - For altered source distributions, you should also note the origin and - nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your - name (or your company's name), and an email address to contact for help or - issues with the library. - - Note that distributing a compiled zlib library along with zlib.h and - zconf.h is also a source distribution, and so you should change - ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes - in zlib.h as you would for a full source distribution. - -25. Will zlib work on a big-endian or little-endian architecture, and can I - exchange compressed data between them? - - Yes and yes. - -26. Will zlib work on a 64-bit machine? - - Yes. It has been tested on 64-bit machines, and has no dependence on any - data types being limited to 32-bits in length. If you have any - difficulties, please provide a complete problem report to zlib@gzip.org - -27. Will zlib decompress data from the PKWare Data Compression Library? - - No. The PKWare DCL uses a completely different compressed data format than - does PKZIP and zlib. However, you can look in zlib's contrib/blast - directory for a possible solution to your problem. - -28. Can I access data randomly in a compressed stream? - - No, not without some preparation. If when compressing you periodically use - Z_FULL_FLUSH, carefully write all the pending data at those points, and - keep an index of those locations, then you can start decompression at those - points. You have to be careful to not use Z_FULL_FLUSH too often, since it - can significantly degrade compression. Alternatively, you can scan a - deflate stream once to generate an index, and then use that index for - random access. See examples/zran.c . - -29. Does zlib work on MVS, OS/390, CICS, etc.? - - It has in the past, but we have not heard of any recent evidence. There - were working ports of zlib 1.1.4 to MVS, but those links no longer work. - If you know of recent, successful applications of zlib on these operating - systems, please let us know. Thanks. - -30. Is there some simpler, easier to read version of inflate I can look at to - understand the deflate format? - - First off, you should read RFC 1951. Second, yes. Look in zlib's - contrib/puff directory. - -31. Does zlib infringe on any patents? - - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: - - http://www.gzip.org/#faq11 - -32. Can zlib work with greater than 4 GB of data? - - Yes. inflate() and deflate() will process any amount of data correctly. - Each call of inflate() or deflate() is limited to input and output chunks - of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These - counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters - updated after each call of inflate() or deflate() to count beyond 4 GB. - compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. - - The word "may" appears several times above since there is a 4 GB limit only - if the compiler's "long" type is 32 bits. If the compiler's "long" type is - 64 bits, then the limit is 16 exabytes. - -33. Does zlib have any security vulnerabilities? - - The only one that we are aware of is potentially in gzprintf(). If zlib is - compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of an 8K string space (or other value as set by - gzbuffer()), other than the caller of gzprintf() assuring that the output - will not exceed 8K. On the other hand, if zlib is compiled to use - snprintf() or vsnprintf(), which should normally be the case, then there is - no vulnerability. The ./configure script will display warnings if an - insecure variation of sprintf() will be used by gzprintf(). Also the - zlibCompileFlags() function will return information on what variant of - sprintf() is used by gzprintf(). - - If you don't have snprintf() or vsnprintf() and would like one, you can - find a portable implementation here: - - http://www.ijs.si/software/snprintf/ - - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability, and versions - 1.2.1 and 1.2.2 were subject to an access exception when decompressing - invalid compressed data. - -34. Is there a Java version of zlib? - - Probably what you want is to use zlib in Java. zlib is already included - as part of the Java SDK in the java.util.zip package. If you really want - a version of zlib written in the Java language, look on the zlib home - page for links: http://zlib.net/ . - -35. I get this or that compiler or source-code scanner warning when I crank it - up to maximally-pedantic. Can't you guys write proper code? - - Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly as well as contradicted each other. So now, we simply - make sure that the code always works. - -36. Valgrind (or some similar memory access checker) says that deflate is - performing a conditional jump that depends on an uninitialized value. - Isn't that a bug? - - No. That is intentional for performance reasons, and the output of deflate - is not affected. This only started showing up recently since zlib 1.2.x - uses malloc() by default for allocations, whereas earlier versions used - calloc(), which zeros out the allocated memory. Even though the code was - correct, versions 1.2.4 and later was changed to not stimulate these - checkers. - -37. Will zlib read the (insert any ancient or arcane format here) compressed - data format? - - Probably not. Look in the comp.compression FAQ for pointers to various - formats and associated software. - -38. How can I encrypt/decrypt zip files with zlib? - - zlib doesn't support encryption. The original PKZIP encryption is very - weak and can be broken with freely available programs. To get strong - encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib - compression. For PKZIP compatible "encryption", look at - http://www.info-zip.org/ - -39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion with - the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 - correctly points to the zlib specification in RFC 1950 for the "deflate" - transfer encoding, there have been reports of servers and browsers that - incorrectly produce or expect raw deflate data per the deflate - specification in RFC 1951, most notably Microsoft. So even though the - "deflate" transfer encoding using the zlib format would be the more - efficient approach (and in fact exactly what the zlib format was designed - for), using the "gzip" transfer encoding is probably more reliable due to - an unfortunate choice of name on the part of the HTTP 1.1 authors. - - Bottom line: use the gzip format for HTTP 1.1 encoding. - -40. Does zlib support the new "Deflate64" format introduced by PKWare? - - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. In - any case, the compression improvements are so modest compared to other more - modern approaches, that it's not worth the effort to implement. - -41. I'm having a problem with the zip functions in zlib, can you help? - - There are no zip functions in zlib. You are probably using minizip by - Giles Vollant, which is found in the contrib directory of zlib. It is not - part of zlib. In fact none of the stuff in contrib is part of zlib. The - files in there are not supported by the zlib authors. You need to contact - the authors of the respective contribution for help. - -42. The match.asm code in contrib is under the GNU General Public License. - Since it's part of zlib, doesn't that mean that all of zlib falls under the - GNU GPL? - - No. The files in contrib are not part of zlib. They were contributed by - other authors and are provided as a convenience to the user within the zlib - distribution. Each item in contrib has its own license. - -43. Is zlib subject to export controls? What is its ECCN? - - zlib is not subject to export controls, and so is classified as EAR99. - -44. Can you please sign these lengthy legal documents and fax them back to us - so that we can use your software in our product? - - No. Go away. Shoo. diff --git a/ModelicaExternalC/C-Sources/zlib/README b/ModelicaExternalC/C-Sources/zlib/README deleted file mode 100644 index 51106de47..000000000 --- a/ModelicaExternalC/C-Sources/zlib/README +++ /dev/null @@ -1,115 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.11 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and -rfc1952 (gzip format). - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file test/example.c which also tests that -the library is working correctly. Another example is given in the file -test/minigzip.c. The compression library itself is composed of all source -files in the root directory. - -To compile all files and run the test program, follow the instructions given at -the top of Makefile.in. In short "./configure; make test", and if that goes -well, "make install" should work for most flavors of Unix. For Windows, use -one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use -make_vms.com. - -Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://zlib.net/ . Before reporting a problem, please check this site to -verify that you have the latest version of zlib; otherwise get the latest -version and check whether the problem still exists or not. - -PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. - -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available at -http://marknelson.us/1997/01/01/zlib-engine/ . - -The changes made in version 1.2.11 are documented in the file ChangeLog. - -Unsupported third party contributions are provided in directory contrib/ . - -zlib is available in Java using the java.util.zip package, documented at -http://java.sun.com/developer/technicalArticles/Programming/compression/ . - -A Perl interface to zlib written by Paul Marquess is available -at CPAN (Comprehensive Perl Archive Network) sites, including -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . - -A Python interface to zlib written by A.M. Kuchling is -available in Python 1.5 and later versions, see -http://docs.python.org/library/zlib.html . - -zlib is built into tcl: http://wiki.tcl.tk/4610 . - -An experimental package to read and write files in .zip format, written on top -of zlib by Gilles Vollant , is available in the -contrib/minizip directory of zlib. - - -Notes for some targets: - -- For Windows DLL versions, please see win32/DLL_FAQ.txt - -- For 64-bit Irix, deflate.c must be compiled without any optimization. With - -O, one libpng test fails. The test works in 32 bit mode (with the -n32 - compiler flag). The compiler bug has been reported to SGI. - -- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works - when compiled with cc. - -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is - necessary to get gzprintf working correctly. This is done by configure. - -- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with - other compilers. Use "make test" to check your compiler. - -- gzdopen is not supported on RISCOS or BEOS. - -- For PalmOs, see http://palmzlib.sourceforge.net/ - - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate and - zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; they - are too numerous to cite here. - -Copyright notice: - - (C) 1995-2017 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* receiving -lengthy legal documents to sign. The sources are provided for free but without -warranty of any kind. The library has been entirely written by Jean-loup -Gailly and Mark Adler; it does not include third-party code. - -If you redistribute modified sources, we would appreciate that you include in -the file ChangeLog history information documenting your changes. Please read -the FAQ for more information on the distribution of modified source versions. diff --git a/ModelicaExternalC/C-Sources/zlib/adler32.c b/ModelicaExternalC/C-Sources/zlib/adler32.c deleted file mode 100644 index d0be4380a..000000000 --- a/ModelicaExternalC/C-Sources/zlib/adler32.c +++ /dev/null @@ -1,186 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - -#define BASE 65521U /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32_z(adler, buf, len) - uLong adler; - const Bytef *buf; - z_size_t len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - return adler32_z(adler, buf, len); -} - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} diff --git a/ModelicaExternalC/C-Sources/zlib/compress.c b/ModelicaExternalC/C-Sources/zlib/compress.c deleted file mode 100644 index e2db404ab..000000000 --- a/ModelicaExternalC/C-Sources/zlib/compress.c +++ /dev/null @@ -1,86 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong left; - - left = *destLen; - *destLen = 0; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; - sourceLen -= stream.avail_in; - } - err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); - } while (err == Z_OK); - - *destLen = stream.total_out; - deflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/ModelicaExternalC/C-Sources/zlib/crc32.c b/ModelicaExternalC/C-Sources/zlib/crc32.c deleted file mode 100644 index 9580440c0..000000000 --- a/ModelicaExternalC/C-Sources/zlib/crc32.c +++ /dev/null @@ -1,442 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -/* Definitions for doing the crc four data bytes at a time. */ -#if !defined(NOBYFOUR) && defined(Z_U4) -# define BYFOUR -#endif -#ifdef BYFOUR - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, z_size_t)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, z_size_t)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); - - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local z_crc_t FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - z_crc_t c; - int n, k; - z_crc_t poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0; - for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) - poly |= (z_crc_t)1 << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (z_crc_t)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = ZSWAP32(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = ZSWAP32(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const z_crc_t FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const z_crc_t FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const z_crc_t FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const z_crc_t FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - z_crc_t endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ - return crc32_z(crc, buf, len); -} - -#ifdef BYFOUR - -/* - This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit - integer pointer type. This violates the strict aliasing rule, where a - compiler can assume, for optimization purposes, that two pointers to - fundamentally different types won't ever point to the same memory. This can - manifest as a problem only if one of the pointers is written to. This code - only reads from those pointers. So long as this code remains isolated in - this compilation unit, there won't be a problem. For this reason, this code - should not be copied and pasted into a compilation unit in which other code - writes to the buffer that is passed to these routines. - */ - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = (z_crc_t)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *buf4++; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = ZSWAP32((z_crc_t)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(ZSWAP32(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} - -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} diff --git a/ModelicaExternalC/C-Sources/zlib/crc32.h b/ModelicaExternalC/C-Sources/zlib/crc32.h deleted file mode 100644 index 9e0c77810..000000000 --- a/ModelicaExternalC/C-Sources/zlib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const z_crc_t FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/ModelicaExternalC/C-Sources/zlib/deflate.c b/ModelicaExternalC/C-Sources/zlib/deflate.c deleted file mode 100644 index 1ec761448..000000000 --- a/ModelicaExternalC/C-Sources/zlib/deflate.c +++ /dev/null @@ -1,2163 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local int deflateStateCheck OF((z_streamp strm)); -local void slide_hash OF((deflate_state *s)); -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV -# pragma message("Assembler code may have bugs -- use at your own risk") - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef ZLIB_DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to UPDATE_HASH are made with consecutive input - * characters, so that a running hash key can be computed from the previous - * key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to INSERT_STRING are made with consecutive input - * characters and the first MIN_MATCH bytes of str are valid (except for - * the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -local void slide_hash(s) - deflate_state *s; -{ - unsigned n, m; - Posf *p; - uInt wsize = s->w_size; - - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - } while (--n); - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif -} - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - s->status = INIT_STATE; /* to pass state test in deflateReset() */ - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = (uInt)windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = (uInt)memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -local int deflateStateCheck (strm) - z_streamp strm; -{ - deflate_state *s; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - s = strm->state; - if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && -#ifdef GZIP - s->status != GZIP_STATE && -#endif - s->status != EXTRA_STATE && - s->status != NAME_STATE && - s->status != COMMENT_STATE && - s->status != HCRC_STATE && - s->status != BUSY_STATE && - s->status != FINISH_STATE)) - return 1; - return 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - z_const unsigned char *next; - - if (deflateStateCheck(strm) || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (z_const Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) - z_streamp strm; - Bytef *dictionary; - uInt *dictLength; -{ - deflate_state *s; - uInt len; - - if (deflateStateCheck(strm)) - return Z_STREAM_ERROR; - s = strm->state; - len = s->strstart + s->lookahead; - if (len > s->w_size) - len = s->w_size; - if (dictionary != Z_NULL && len) - zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); - if (dictLength != Z_NULL) - *dictLength = len; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep (strm) - z_streamp strm; -{ - deflate_state *s; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = -#ifdef GZIP - s->wrap == 2 ? GZIP_STATE : -#endif - s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (deflateStateCheck(strm) || strm->state->wrap != 2) - return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending (strm, pending, bits) - unsigned *pending; - int *bits; - z_streamp strm; -{ - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - deflate_state *s; - int put; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - s->high_water) { - /* Flush the last buffer: */ - int err = deflate(strm, Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; - if (strm->avail_out == 0) - return Z_BUF_ERROR; - } - if (s->level != level) { - if (s->level == 0 && s->matches != 0) { - if (s->matches == 1) - slide_hash(s); - else - CLEAR_HASH(s); - s->matches = 0; - } - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = (uInt)good_length; - s->max_lazy_match = (uInt)max_lazy; - s->nice_match = nice_length; - s->max_chain_length = (uInt)max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong complen, wraplen; - - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (deflateStateCheck(strm)) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; -#ifdef GZIP - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - Bytef *str; - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; -#endif - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* =========================================================================== - * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. - */ -#define HCRC_UPDATE(beg) \ - do { \ - if (s->gzhead->hcrc && s->pending > (beg)) \ - strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ - s->pending - (beg)); \ - } while (0) - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->avail_in != 0 && strm->next_in == Z_NULL) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - old_flush = s->last_flush; - s->last_flush = flush; - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Write the header */ - if (s->status == INIT_STATE) { - /* zlib header */ - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#ifdef GZIP - if (s->status == GZIP_STATE) { - /* gzip header */ - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; - while (s->pending + left > s->pending_buf_size) { - uInt copy = s->pending_buf_size - s->pending; - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, copy); - s->pending = s->pending_buf_size; - HCRC_UPDATE(beg); - s->gzindex += copy; - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - left -= copy; - } - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, left); - s->pending += left; - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - } - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) { - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - } - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#endif - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->level == 0 ? deflate_stored(s, flush) : - s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - - status = strm->state->status; - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (deflateStateCheck(source) || dest == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = (int)s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef ZLIB_DEBUG - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* ZLIB_DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* Maximum stored block length in deflate format (not including header). */ -#define MAX_STORED 65535 - -/* Minimum of a and b. */ -#define MIN(a, b) ((a) > (b) ? (b) : (a)) - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - unsigned len, left, have, last = 0; - unsigned used = s->strm->avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = MAX_STORED; /* maximum deflate stored block length */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - if (s->strm->avail_out < have) /* need room for header */ - break; - /* maximum stored block length that will fit in avail_out: */ - have = s->strm->avail_out - have; - left = s->strstart - s->block_start; /* bytes left in window */ - if (len > (ulg)left + s->strm->avail_in) - len = left + s->strm->avail_in; /* limit len to the input */ - if (len > have) - len = have; /* limit len to the output */ - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len == 0 && flush != Z_FINISH) || - flush == Z_NO_FLUSH || - len != left + s->strm->avail_in)) - break; - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; - _tr_stored_block(s, (char *)0, 0L, last); - - /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = len; - s->pending_buf[s->pending - 3] = len >> 8; - s->pending_buf[s->pending - 2] = ~len; - s->pending_buf[s->pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending(s->strm); - -#ifdef ZLIB_DEBUG - /* Update debugging counts for the data about to be copied. */ - s->compressed_len += len << 3; - s->bits_sent += len << 3; -#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) - left = len; - zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s->strm->next_out += left; - s->strm->avail_out -= left; - s->strm->total_out += left; - s->block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s->strm, s->strm->next_out, len); - s->strm->next_out += len; - s->strm->avail_out -= len; - s->strm->total_out += len; - } - } while (last == 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s->strm->avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s->w_size) { /* supplant the previous history */ - s->matches = 2; /* clear hash */ - zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s->strstart = s->w_size; - } - else { - if (s->window_size - s->strstart <= used) { - /* Slide the window down. */ - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - } - zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s->strstart += used; - } - s->block_start = s->strstart; - s->insert += MIN(used, s->w_size - s->insert); - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* If the last block was written to next_out, then done. */ - if (last) - return finish_done; - - /* If flushing and all input has been consumed, then done. */ - if (flush != Z_NO_FLUSH && flush != Z_FINISH && - s->strm->avail_in == 0 && (long)s->strstart == s->block_start) - return block_done; - - /* Fill the window with any remaining input. */ - have = s->window_size - s->strstart - 1; - if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { - /* Slide the window down. */ - s->block_start -= s->w_size; - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - have += s->w_size; /* more space now */ - } - if (have > s->strm->avail_in) - have = s->strm->avail_in; - if (have) { - read_buf(s->strm, s->window + s->strstart, have); - s->strstart += have; - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = MIN(s->pending_buf_size - have, MAX_STORED); - min_block = MIN(have, s->w_size); - left = s->strstart - s->block_start; - if (left >= min_block || - ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && - s->strm->avail_in == 0 && left <= have)) { - len = MIN(left, have); - last = flush == Z_FINISH && s->strm->avail_in == 0 && - len == left ? 1 : 0; - _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); - s->block_start += len; - flush_pending(s->strm); - } - - /* We've done all we can with the available input and output. */ - return last ? finish_started : need_more; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (uInt)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/ModelicaExternalC/C-Sources/zlib/deflate.h b/ModelicaExternalC/C-Sources/zlib/deflate.h deleted file mode 100644 index 23ecdd312..000000000 --- a/ModelicaExternalC/C-Sources/zlib/deflate.h +++ /dev/null @@ -1,349 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2016 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define Buf_size 16 -/* size of bit buffer in bi_buf */ - -#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ -#ifdef GZIP -# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ -#endif -#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ -#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ -#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ -#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ -#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ -#define FINISH_STATE 666 /* stream complete */ -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - const static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - ulg pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - ulg gzindex; /* where in extra, name, or comment */ - Byte method; /* can only be DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - uInt insert; /* bytes at end of window left to insert */ - -#ifdef ZLIB_DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef ZLIB_DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/ModelicaExternalC/C-Sources/zlib/gzclose.c b/ModelicaExternalC/C-Sources/zlib/gzclose.c deleted file mode 100644 index caeb99a31..000000000 --- a/ModelicaExternalC/C-Sources/zlib/gzclose.c +++ /dev/null @@ -1,25 +0,0 @@ -/* gzclose.c -- zlib gzclose() function - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* gzclose() is in a separate file so that it is linked in only if it is used. - That way the other gzclose functions can be used instead to avoid linking in - unneeded compression or decompression routines. */ -int ZEXPORT gzclose(file) - gzFile file; -{ -#ifndef NO_GZCOMPRESS - gz_statep state; - - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); -#else - return gzclose_r(file); -#endif -} diff --git a/ModelicaExternalC/C-Sources/zlib/gzguts.h b/ModelicaExternalC/C-Sources/zlib/gzguts.h deleted file mode 100644 index 01a2d5e01..000000000 --- a/ModelicaExternalC/C-Sources/zlib/gzguts.h +++ /dev/null @@ -1,221 +0,0 @@ -/* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef _LARGEFILE64_SOURCE -# ifndef _LARGEFILE_SOURCE -# define _LARGEFILE_SOURCE 1 -# endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif -#endif - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include -#include "zlib.h" -#ifdef STDC -# include -# include -# include -#endif - -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif -#include - -#ifdef _WIN32 -# include -#endif - -#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) -# include -#endif - -#if defined(_WIN32) || defined(__CYGWIN__) -# define WIDECHAR -#endif - -#ifdef WINAPI_FAMILY -# define open _open -# define read _read -# define write _write -# define close _close -#endif - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS -/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 -/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -# ifdef VMS -# define NO_vsnprintf -# endif -# ifdef __OS400__ -# define NO_vsnprintf -# endif -# ifdef __MVS__ -# define NO_vsnprintf -# endif -# ifndef STDC99 -# define NO_vsnprintf -# endif -#endif - -/* unlike snprintf (which is required in C99), _snprintf does not guarantee - null termination of the result -- however this is only used in gzlib.c where - the result is assured to fit in the space provided */ -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -/* gz* functions always use library allocation functions */ -#ifndef STDC - extern voidp malloc OF((uInt size)); - extern void free OF((voidpf ptr)); -#endif - -/* get errno and strerror definition */ -#if defined UNDER_CE -# include -# define zstrerror() gz_strwinerror((DWORD)GetLastError()) -#else -# ifndef NO_STRERROR -# include -# define zstrerror() strerror(errno) -# else -# define zstrerror() "stdio error (consult errno)" -# endif -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); -#endif - -/* default memLevel */ -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -/* default i/o buffer size -- double this for output when reading (this and - twice this must be able to fit in an unsigned type) */ -#define GZBUFSIZE 8192 - -/* gzip modes, also provide a little integrity check on the passed structure */ -#define GZ_NONE 0 -#define GZ_READ 7247 -#define GZ_WRITE 31153 -#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ - -/* values for gz_state how */ -#define LOOK 0 /* look for a gzip header */ -#define COPY 1 /* copy input directly */ -#define GZIP 2 /* decompress a gzip stream */ - -/* internal gzip file state data structure */ -typedef struct { - /* exposed contents for gzgetc() macro */ - struct gzFile_s x; /* "x" for exposed */ - /* x.have: number of bytes available at x.next */ - /* x.next: next output data to deliver or write */ - /* x.pos: current position in uncompressed data */ - /* used for both reading and writing */ - int mode; /* see gzip modes above */ - int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ - unsigned size; /* buffer size, zero if not allocated yet */ - unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer (double-sized when writing) */ - unsigned char *out; /* output buffer (double-sized when reading) */ - int direct; /* 0 if processing gzip, 1 if transparent */ - /* just for reading */ - int how; /* 0: get header, 1: copy, 2: decompress */ - z_off64_t start; /* where the gzip data started, for rewinding */ - int eof; /* true if end of input file reached */ - int past; /* true if read requested past end */ - /* just for writing */ - int level; /* compression level */ - int strategy; /* compression strategy */ - /* seek request */ - z_off64_t skip; /* amount to skip (already rewound if backwards) */ - int seek; /* true if seek request pending */ - /* error information */ - int err; /* error code */ - char *msg; /* error message */ - /* zlib inflate or deflate stream */ - z_stream strm; /* stream structure in-place (not a pointer) */ -} gz_state; -typedef gz_state FAR *gz_statep; - -/* shared functions */ -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); -#if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); -#endif - -/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t - value -- needed when comparing unsigned to z_off64_t, which is signed - (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else -unsigned ZLIB_INTERNAL gz_intmax OF((void)); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif diff --git a/ModelicaExternalC/C-Sources/zlib/gzlib.c b/ModelicaExternalC/C-Sources/zlib/gzlib.c deleted file mode 100644 index 4105e6aff..000000000 --- a/ModelicaExternalC/C-Sources/zlib/gzlib.c +++ /dev/null @@ -1,637 +0,0 @@ -/* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) -# define LSEEK _lseeki64 -#else -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 -#else -# define LSEEK lseek -#endif -#endif - -/* Local functions */ -local void gz_reset OF((gz_statep)); -local gzFile gz_open OF((const void *, int, const char *)); - -#if defined UNDER_CE - -/* Map the Windows error number in ERROR to a locale-dependent error message - string and return a pointer to it. Typically, the values for ERROR come - from GetLastError. - - The string pointed to shall not be modified by the application, but may be - overwritten by a subsequent call to gz_strwinerror - - The gz_strwinerror function does not change the current setting of - GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror (error) - DWORD error; -{ - static char buf[1024]; - - wchar_t *msgbuf; - DWORD lasterr = GetLastError(); - DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - error, - 0, /* Default language */ - (LPVOID)&msgbuf, - 0, - NULL); - if (chars != 0) { - /* If there is an \r\n appended, zap it. */ - if (chars >= 2 - && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { - chars -= 2; - msgbuf[chars] = 0; - } - - if (chars > sizeof (buf) - 1) { - chars = sizeof (buf) - 1; - msgbuf[chars] = 0; - } - - wcstombs(buf, msgbuf, chars + 1); - LocalFree(msgbuf); - } - else { - sprintf(buf, "unknown win32 error (%ld)", error); - } - - SetLastError(lasterr); - return buf; -} - -#endif /* UNDER_CE */ - -/* Reset gzip file state */ -local void gz_reset(state) - gz_statep state; -{ - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ - } - state->seek = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ -} - -/* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(path, fd, mode) - const void *path; - int fd; - const char *mode; -{ - gz_statep state; - z_size_t len; - int oflag; -#ifdef O_CLOEXEC - int cloexec = 0; -#endif -#ifdef O_EXCL - int exclusive = 0; -#endif - - /* check input */ - if (path == NULL) - return NULL; - - /* allocate gzFile structure to return */ - state = (gz_statep)malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ - - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; - while (*mode) { - if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; - else - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; -#ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; -#endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; -#ifdef O_CLOEXEC - case 'e': - cloexec = 1; - break; -#endif -#ifdef O_EXCL - case 'x': - exclusive = 1; - break; -#endif - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - break; - case 'T': - state->direct = 1; - break; - default: /* could consider as an error, but just ignore */ - ; - } - mode++; - } - - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } - - /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); - return NULL; - } - state->direct = 1; /* for empty file */ - } - - /* save the path name for error messages */ -#ifdef WIDECHAR - if (fd == -2) { - len = wcstombs(NULL, path, 0); - if (len == (z_size_t)-1) - len = 0; - } - else -#endif - len = strlen((const char *)path); - state->path = (char *)malloc(len + 1); - if (state->path == NULL) { - free(state); - return NULL; - } -#ifdef WIDECHAR - if (fd == -2) - if (len) - wcstombs(state->path, path, len + 1); - else - *(state->path) = 0; - else -#endif -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(state->path, len + 1, "%s", (const char *)path); -#else - strcpy(state->path, path); -#endif - - /* compute the flags for open() */ - oflag = -#ifdef O_LARGEFILE - O_LARGEFILE | -#endif -#ifdef O_BINARY - O_BINARY | -#endif -#ifdef O_CLOEXEC - (cloexec ? O_CLOEXEC : 0) | -#endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | -#ifdef O_EXCL - (exclusive ? O_EXCL : 0) | -#endif - (state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))); - - /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( -#ifdef WIDECHAR - fd == -2 ? _wopen(path, oflag, 0666) : -#endif - open((const char *)path, oflag, 0666)); - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) { - LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ - state->mode = GZ_WRITE; /* simplify later checks */ - } - - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } - - /* initialize stream */ - gz_reset(state); - - /* return stream */ - return (gzFile)state; -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(fd, mode) - int fd; - const char *mode; -{ - char *path; /* identifier for error messages */ - gzFile gz; - - if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); -#else - sprintf(path, "", fd); /* for debugging */ -#endif - gz = gz_open(path, fd, mode); - free(path); - return gz; -} - -/* -- see zlib.h -- */ -#ifdef WIDECHAR -gzFile ZEXPORT gzopen_w(path, mode) - const wchar_t *path; - const char *mode; -{ - return gz_open(path, -2, mode); -} -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzbuffer(file, size) - gzFile file; - unsigned size; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; - - /* check and set requested size */ - if ((size << 1) < size) - return -1; /* need to be able to double it */ - if (size < 2) - size = 2; /* need two bytes to check magic header */ - state->want = size; - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzrewind(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(file, offset, whence) - gzFile file; - z_off64_t offset; - int whence; -{ - unsigned n; - z_off64_t ret; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; - - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; - - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); - if (ret == -1) - return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; - } - - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } - - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - offset -= n; - } - - /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } - return state->x.pos + offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - z_off64_t ret; - - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(file) - gzFile file; -{ - z_off64_t ret; - - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(file) - gzFile file; -{ - z_off64_t offset; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(file) - gzFile file; -{ - z_off64_t ret; - - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzeof(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; - - /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; -} - -/* -- see zlib.h -- */ -const char * ZEXPORT gzerror(file, errnum) - gzFile file; - int *errnum; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; - - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->err == Z_MEM_ERROR ? "out of memory" : - (state->msg == NULL ? "" : state->msg); -} - -/* -- see zlib.h -- */ -void ZEXPORT gzclearerr(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; - - /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; - } - gz_error(state, Z_OK, NULL); -} - -/* Create an error message in allocated memory and set state->err and - state->msg accordingly. Free any previous error message already there. Do - not try to free or allocate space if the error is Z_MEM_ERROR (out of - memory). Simply save the error message as a static string. If there is an - allocation failure constructing the error message, then convert the error to - out of memory. */ -void ZLIB_INTERNAL gz_error(state, err, msg) - gz_statep state; - int err; - const char *msg; -{ - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } - - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; - - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; - - /* for an out of memory error, return literal string when requested */ - if (err == Z_MEM_ERROR) - return; - - /* construct error message with path */ - if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == - NULL) { - state->err = Z_MEM_ERROR; - return; - } -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); -#else - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); -#endif -} - -#ifndef INT_MAX -/* portably return maximum value for an int (when limits.h presumed not - available) -- we need to do this to cover cases where 2's complement not - used, since C standard permits 1's complement and sign-bit representations, - otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax() -{ - unsigned p, q; - - p = 1; - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; -} -#endif diff --git a/ModelicaExternalC/C-Sources/zlib/gzread.c b/ModelicaExternalC/C-Sources/zlib/gzread.c deleted file mode 100644 index 956b91ea7..000000000 --- a/ModelicaExternalC/C-Sources/zlib/gzread.c +++ /dev/null @@ -1,654 +0,0 @@ -/* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); -local int gz_avail OF((gz_statep)); -local int gz_look OF((gz_statep)); -local int gz_decomp OF((gz_statep)); -local int gz_fetch OF((gz_statep)); -local int gz_skip OF((gz_statep, z_off64_t)); -local z_size_t gz_read OF((gz_statep, voidp, z_size_t)); - -/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from - state->fd, and update state->eof, state->err, and state->msg as appropriate. - This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(state, buf, len, have) - gz_statep state; - unsigned char *buf; - unsigned len; - unsigned *have; -{ - int ret; - unsigned get, max = ((unsigned)-1 >> 2) + 1; - - *have = 0; - do { - get = len - *have; - if (get > max) - get = max; - ret = read(state->fd, buf + *have, get); - if (ret <= 0) - break; - *have += (unsigned)ret; - } while (*have < len); - if (ret < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; -} - -/* Load up input buffer and set eof flag if last data loaded -- return -1 on - error, 0 otherwise. Note that the eof flag is set when the end of the input - file is reached, even though there may be unused data in the buffer. Once - that data has been used, no more attempts will be made to read the file. - If strm->avail_in != 0, then the current data is moved to the beginning of - the input buffer, and then the remainder of the buffer is loaded with the - available data from the input file. */ -local int gz_avail(state) - gz_statep state; -{ - unsigned got; - z_streamp strm = &(state->strm); - - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->eof == 0) { - if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in; - unsigned const char *q = strm->next_in; - unsigned n = strm->avail_in; - do { - *p++ = *q++; - } while (--n); - } - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) - return -1; - strm->avail_in += got; - strm->next_in = state->in; - } - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. - If this is the first time in, allocate required memory. state->how will be - left unchanged if there is no more input data available, will be set to COPY - if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression. If direct copying, then leftover input - data from the input buffer will be copied to the output buffer. In that - case, all further file reads will be directly to either the output buffer or - a user buffer. If decompressing, the inflate state will be initialized. - gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = (unsigned char *)malloc(state->want); - state->out = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; - - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* get at least the magic bytes in the input buffer */ - if (strm->avail_in < 2) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } - - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is - a logical dilemma here when considering the case of a partially written - gzip file, to wit, if a single 31 byte is written, then we cannot tell - whether this is a single-byte file, or just a partially written gzip - file -- for here we assume that if a gzip file is being written, then - the header will be written in a single operation, so that reading a - single byte is sufficient indication that it is not a gzip file) */ - if (strm->avail_in > 1 && - strm->next_in[0] == 31 && strm->next_in[1] == 139) { - inflateReset(strm); - state->how = GZIP; - state->direct = 0; - return 0; - } - - /* no gzip header -- if we were decoding gzip before, then this is trailing - garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { - strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; - return 0; - } - - /* doing raw i/o, copy any leftover input to output -- this assumes that - the output buffer is larger than the input buffer, which also assures - space for gzungetc() */ - state->x.next = state->out; - if (strm->avail_in) { - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - } - state->how = COPY; - state->direct = 1; - return 0; -} - -/* Decompress from input to the provided next_out and avail_out in the state. - On return, state->x.have and state->x.next point to the just decompressed - data. If the gzip stream completes, state->how is reset to LOOK to look for - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 - on success, -1 on failure. */ -local int gz_decomp(state) - gz_statep state; -{ - int ret = Z_OK; - unsigned had; - z_streamp strm = &(state->strm); - - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) { - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); - break; - } - - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); - return -1; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; - } - } while (strm->avail_out && ret != Z_STREAM_END); - - /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; - - /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) - state->how = LOOK; - - /* good decompression */ - return 0; -} - -/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. - Data is either copied from the input file or decompressed from the input - file depending on state->how. If state->how is LOOK, then a gzip header is - looked for to determine whether to copy or decompress. Returns -1 on error, - otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the - end of the input file has been reached and all data has been processed. */ -local int gz_fetch(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - do { - switch(state->how) { - case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ - if (gz_look(state) == -1) - return -1; - if (state->how == LOOK) - return 0; - break; - case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) - == -1) - return -1; - state->x.next = state->out; - return 0; - case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); - return 0; -} - -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(state, len) - gz_statep state; - z_off64_t len; -{ - unsigned n; - - /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) - /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - len -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; - - /* need more data to skip -- load up output buffer */ - else { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - } - return 0; -} - -/* Read len bytes into buf from file, or less than len up to the end of the - input. Return the number of bytes read. If zero is returned, either the - end of file was reached, or there was an error. state->err must be - consulted in that case to determine which. */ -local z_size_t gz_read(state, buf, len) - gz_statep state; - voidp buf; - z_size_t len; -{ - z_size_t got; - unsigned n; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return 0; - } - - /* get len bytes to buf, or less than len if at the end */ - got = 0; - do { - /* set n to the maximum amount of len that fits in an unsigned int */ - n = -1; - if (n > len) - n = len; - - /* first just try copying data from the output buffer */ - if (state->x.have) { - if (state->x.have < n) - n = state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) { - state->past = 1; /* tried to read past end */ - break; - } - - /* need output data -- for small len or new stream load up our output - buffer */ - else if (state->how == LOOK || n < (state->size << 1)) { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return 0; - continue; /* no progress yet -- go back to copy above */ - /* the copy above assures that we will leave with space in the - output buffer, allowing at least one gzungetc() to succeed */ - } - - /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ - if (gz_load(state, (unsigned char *)buf, n, &n) == -1) - return 0; - } - - /* large len -- decompress directly into user buffer */ - else { /* state->how == GZIP */ - state->strm.avail_out = n; - state->strm.next_out = (unsigned char *)buf; - if (gz_decomp(state) == -1) - return 0; - n = state->x.have; - state->x.have = 0; - } - - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->x.pos += n; - } while (len); - - /* return number of bytes read into user buffer */ - return got; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzread(file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); - return -1; - } - - /* read len or fewer bytes to buf */ - len = gz_read(state, buf, len); - - /* check for an error */ - if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* return the number of bytes read (this is assured to fit in an int) */ - return (int)len; -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfread(buf, size, nitems, file) - voidp buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return 0; - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* read len or fewer bytes to buf, return the number of full items read */ - return len ? gz_read(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -#else -# undef gzgetc -#endif -int ZEXPORT gzgetc(file) - gzFile file; -{ - int ret; - unsigned char buf[1]; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; - } - - /* nothing there -- try gz_read() */ - ret = gz_read(state, buf, 1); - return ret < 1 ? -1 : buf[0]; -} - -int ZEXPORT gzgetc_(file) -gzFile file; -{ - return gzgetc(file); -} - -/* -- see zlib.h -- */ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) - *--dest = *--src; - state->x.next = dest; - } - state->x.have++; - state->x.next--; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters and get internal structure */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return NULL; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } - - /* copy output bytes up to new line or len - 1, whichever comes first -- - append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ - break; /* return what we have */ - } - - /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = (unsigned char *)memchr(state->x.next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; - - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); - - /* return terminated string, or if nothing, end of file */ - if (buf == str) - return NULL; - buf[0] = 0; - return str; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzdirect(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* if the state is not known, but we can find out, then do so (this is - mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_r(file) - gzFile file; -{ - int ret, err; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're reading */ - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; - - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : err; -} diff --git a/ModelicaExternalC/C-Sources/zlib/gzwrite.c b/ModelicaExternalC/C-Sources/zlib/gzwrite.c deleted file mode 100644 index c7b5651d7..000000000 --- a/ModelicaExternalC/C-Sources/zlib/gzwrite.c +++ /dev/null @@ -1,665 +0,0 @@ -/* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_init OF((gz_statep)); -local int gz_comp OF((gz_statep, int)); -local int gz_zero OF((gz_statep, z_off64_t)); -local z_size_t gz_write OF((gz_statep, voidpc, z_size_t)); - -/* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on a memory allocation failure, or 0 on - success. */ -local int gz_init(state) - gz_statep state; -{ - int ret; - z_streamp strm = &(state->strm); - - /* allocate input buffer (double size for gzprintf) */ - state->in = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* only need output buffer and deflate state if compressing */ - if (!state->direct) { - /* allocate output buffer */ - state->out = (unsigned char *)malloc(state->want); - if (state->out == NULL) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); - if (ret != Z_OK) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - strm->next_in = NULL; - } - - /* mark state as initialized */ - state->size = state->want; - - /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; - } - return 0; -} - -/* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file or if gz_init() - fails to allocate memory, otherwise 0. flush is assumed to be a valid - deflate() flush value. If flush is Z_FINISH, then the deflate() state is - reset to start a new gzip stream. If gz->direct is true, then simply write - to the output file without compressing, and ignore flush. */ -local int gz_comp(state, flush) - gz_statep state; - int flush; -{ - int ret, writ; - unsigned have, put, max = ((unsigned)-1 >> 2) + 1; - z_streamp strm = &(state->strm); - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; - - /* write directly if requested */ - if (state->direct) { - while (strm->avail_in) { - put = strm->avail_in > max ? max : strm->avail_in; - writ = write(state->fd, strm->next_in, put); - if (writ < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - strm->avail_in -= (unsigned)writ; - strm->next_in += writ; - } - return 0; - } - - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if - doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && - (flush != Z_FINISH || ret == Z_STREAM_END))) { - while (strm->next_out > state->x.next) { - put = strm->next_out - state->x.next > (int)max ? max : - (unsigned)(strm->next_out - state->x.next); - writ = write(state->fd, state->x.next, put); - if (writ < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - state->x.next += writ; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = state->out; - } - } - - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, - "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); - - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - deflateReset(strm); - - /* all done, no errors */ - return 0; -} - -/* Compress len zeros to output. Return -1 on a write error or memory - allocation failure by gz_comp(), or 0 on success. */ -local int gz_zero(state, len) - gz_statep state; - z_off64_t len; -{ - int first; - unsigned n; - z_streamp strm = &(state->strm); - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - - /* compress len zeros (len guaranteed > 0) */ - first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - len -= n; - } - return 0; -} - -/* Write len bytes from buf to file. Return the number of bytes written. If - the returned value is less than len, then there was an error. */ -local z_size_t gz_write(state, buf, len) - gz_statep state; - voidpc buf; - z_size_t len; -{ - z_size_t put = len; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - do { - unsigned have, copy; - - if (state->strm.avail_in == 0) - state->strm.next_in = state->in; - have = (unsigned)((state->strm.next_in + state->strm.avail_in) - - state->in); - copy = state->size - have; - if (copy > len) - copy = len; - memcpy(state->in + have, buf, copy); - state->strm.avail_in += copy; - state->x.pos += copy; - buf = (const char *)buf + copy; - len -= copy; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); - } - else { - /* consume whatever's left in the input buffer */ - if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* directly compress user buffer to file */ - state->strm.next_in = (z_const Bytef *)buf; - do { - unsigned n = (unsigned)-1; - if (n > len) - n = len; - state->strm.avail_in = n; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - len -= n; - } while (len); - } - - /* input was all buffered or compressed */ - return put; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } - - /* write len bytes from buf (the return value will fit in an int) */ - return (int)gz_write(state, buf, len); -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) - voidpc buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* write len bytes to buf, return the number of full items written */ - return len ? gz_write(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned have; - unsigned char buf[1]; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* try writing to input buffer for speed (state->size == 0 if buffer not - initialized) */ - if (state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - if (have < state->size) { - state->in[have] = (unsigned char)c; - strm->avail_in++; - state->x.pos++; - return c & 0xff; - } - } - - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = (unsigned char)c; - if (gz_write(state, buf, 1) != 1) - return -1; - return c & 0xff; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputs(file, str) - gzFile file; - const char *str; -{ - int ret; - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* write string */ - len = strlen(str); - ret = gz_write(state, str, len); - return ret == 0 && len != 0 ? -1 : ret; -} - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -#include - -/* -- see zlib.h -- */ -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) -{ - int len; - unsigned left; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->err; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(next, format, va); - for (len = 0; len < state->size; len++) - if (next[len] == 0) break; -# else - len = vsprintf(next, format, va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(next, state->size, format, va); - len = strlen(next); -# else - len = vsnprintf(next, state->size, format, va); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += (unsigned)len; - state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memcpy(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } - return len; -} - -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) -{ - va_list va; - int ret; - - va_start(va, format); - ret = gzvprintf(file, format, va); - va_end(va); - return ret; -} - -#else /* !STDC && !Z_HAVE_STDARG_H */ - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - unsigned len, left; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that can really pass pointer in ints */ - if (sizeof(int) != sizeof(void *)) - return Z_STREAM_ERROR; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->error; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->error; - } - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(strm->next_in + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, - a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < size; len++) - if (next[len] == 0) - break; -# else - len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, - a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, - a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(next); -# else - len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += len; - state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memcpy(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } - return (int)len; -} - -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzflush(file, flush) - gzFile file; - int flush; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* compress remaining data with requested flush */ - (void)gz_comp(state, flush); - return state->err; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzsetparams(file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_w(file) - gzFile file; -{ - int ret = Z_OK; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; - } - - /* flush, free memory, and close file */ - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (state->size) { - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); - } - free(state->in); - } - gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) - ret = Z_ERRNO; - free(state); - return ret; -} diff --git a/ModelicaExternalC/C-Sources/zlib/infback.c b/ModelicaExternalC/C-Sources/zlib/infback.c deleted file mode 100644 index 59679ecbf..000000000 --- a/ModelicaExternalC/C-Sources/zlib/infback.c +++ /dev/null @@ -1,640 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = (uInt)windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/ModelicaExternalC/C-Sources/zlib/inffast.c b/ModelicaExternalC/C-Sources/zlib/inffast.c deleted file mode 100644 index 0dbd1dbc0..000000000 --- a/ModelicaExternalC/C-Sources/zlib/inffast.c +++ /dev/null @@ -1,323 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef ASMINF -# pragma message("Assembler code may have bugs -- use at your own risk") -#else - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in; - last = in + (strm->avail_in - 5); - out = strm->next_out; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - *out++ = (unsigned char)(here.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - *out++ = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - *out++ = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - *out++ = *from++; - } while (--len); - continue; - } -#endif - } - from = window; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = window; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in; - strm->next_out = out; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/ModelicaExternalC/C-Sources/zlib/inffast.h b/ModelicaExternalC/C-Sources/zlib/inffast.h deleted file mode 100644 index e5c1aa4ca..000000000 --- a/ModelicaExternalC/C-Sources/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/ModelicaExternalC/C-Sources/zlib/inffixed.h b/ModelicaExternalC/C-Sources/zlib/inffixed.h deleted file mode 100644 index d62832776..000000000 --- a/ModelicaExternalC/C-Sources/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/ModelicaExternalC/C-Sources/zlib/inflate.c b/ModelicaExternalC/C-Sources/zlib/inflate.c deleted file mode 100644 index ac333e8c2..000000000 --- a/ModelicaExternalC/C-Sources/zlib/inflate.c +++ /dev/null @@ -1,1561 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); - -local int inflateStateCheck(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - state = (struct inflate_state FAR *)strm->state; - if (state == Z_NULL || state->strm != strm || - state->mode < HEAD || state->mode > SYNC) - return 1; - return 0; -} - -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->strm = strm; - state->window = Z_NULL; - state->mode = HEAD; /* to pass state test in inflateReset2() */ - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; - state->bits += (uInt)bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, end, copy) -z_streamp strm; -const Bytef *end; -unsigned copy; -{ - struct inflate_state FAR *state; - unsigned dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (inflateStateCheck(strm) || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if ((state->wrap & 4) && hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if ((state->wrap & 4) && ( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long dictid; - int ret; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -const unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - copy->strm = dest; - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - state->sane = !subvert; - return Z_OK; -#else - (void)subvert; - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -int ZEXPORT inflateValidate(strm, check) -z_streamp strm; -int check; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (check) - state->wrap |= 4; - else - state->wrap &= ~4; - return Z_OK; -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) - return -(1L << 16); - state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} - -unsigned long ZEXPORT inflateCodesUsed(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long)-1; - state = (struct inflate_state FAR *)strm->state; - return (unsigned long)(state->next - state->codes); -} diff --git a/ModelicaExternalC/C-Sources/zlib/inflate.h b/ModelicaExternalC/C-Sources/zlib/inflate.h deleted file mode 100644 index a46cce6b6..000000000 --- a/ModelicaExternalC/C-Sources/zlib/inflate.h +++ /dev/null @@ -1,125 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD = 16180, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* State maintained between inflate() calls -- approximately 7K bytes, not - including the allocated sliding window, which is up to 32K bytes. */ -struct inflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/ModelicaExternalC/C-Sources/zlib/inftrees.c b/ModelicaExternalC/C-Sources/zlib/inftrees.c deleted file mode 100644 index 2ea08fc13..000000000 --- a/ModelicaExternalC/C-Sources/zlib/inftrees.c +++ /dev/null @@ -1,304 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.11 Copyright 1995-2017 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - unsigned match; /* use base and extra for symbol >= match */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - match = 20; - break; - case LENS: - base = lbase; - extra = lext; - match = 257; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - match = 0; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if (work[sym] + 1U < match) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if (work[sym] >= match) { - here.op = (unsigned char)(extra[work[sym] - match]); - here.val = base[work[sym] - match]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/ModelicaExternalC/C-Sources/zlib/inftrees.h b/ModelicaExternalC/C-Sources/zlib/inftrees.h deleted file mode 100644 index fa95ae638..000000000 --- a/ModelicaExternalC/C-Sources/zlib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distributions. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/ModelicaExternalC/C-Sources/zlib/trees.c b/ModelicaExternalC/C-Sources/zlib/trees.c deleted file mode 100644 index 50cf4b457..000000000 --- a/ModelicaExternalC/C-Sources/zlib/trees.c +++ /dev/null @@ -1,1203 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2017 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef ZLIB_DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local const static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local const static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local const static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, const ct_data *ltree, - const ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef ZLIB_DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* !ZLIB_DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef ZLIB_DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !ZLIB_DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = (int)value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* ZLIB_DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef ZLIB_DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (unsigned)(bits + xbits); - if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); - } - if (overflow == 0) return; - - Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits-1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, (ush)stored_len); - put_short(s, (ush)~stored_len); - zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); - s->pending += stored_len; -#ifdef ZLIB_DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - s->bits_sent += 2*16; - s->bits_sent += stored_len<<3; -#endif -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(s) - deflate_state *s; -{ - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef ZLIB_DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (const ct_data *)static_ltree, - (const ct_data *)static_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (const ct_data *)s->dyn_ltree, - (const ct_data *)s->dyn_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef ZLIB_DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - const ct_data *ltree; /* literal tree */ - const ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} diff --git a/ModelicaExternalC/C-Sources/zlib/trees.h b/ModelicaExternalC/C-Sources/zlib/trees.h deleted file mode 100644 index d35639d82..000000000 --- a/ModelicaExternalC/C-Sources/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/ModelicaExternalC/C-Sources/zlib/uncompr.c b/ModelicaExternalC/C-Sources/zlib/uncompr.c deleted file mode 100644 index f03a1a865..000000000 --- a/ModelicaExternalC/C-Sources/zlib/uncompr.c +++ /dev/null @@ -1,93 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. *sourceLen is - the byte length of the source buffer. Upon entry, *destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, - *destLen is the size of the decompressed data and *sourceLen is the number - of source bytes consumed. Upon return, source + *sourceLen points to the - first unused input byte. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, or - Z_DATA_ERROR if the input data was corrupted, including if the input data is - an incomplete zlib stream. -*/ -int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong *sourceLen; -{ - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong len, left; - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ - - len = *sourceLen; - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } - - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = len > (uLong)max ? max : (uInt)len; - len -= stream.avail_in; - } - err = inflate(&stream, Z_NO_FLUSH); - } while (err == Z_OK); - - *sourceLen -= len + stream.avail_in; - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; - - inflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : - err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : - err; -} - -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return uncompress2(dest, destLen, source, &sourceLen); -} diff --git a/ModelicaExternalC/C-Sources/zlib/zconf.h b/ModelicaExternalC/C-Sources/zlib/zconf.h deleted file mode 100644 index 5e1d68a00..000000000 --- a/ModelicaExternalC/C-Sources/zlib/zconf.h +++ /dev/null @@ -1,534 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols and init macros */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define adler32_z z_adler32_z -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzfread z_gzfread -# define gzfwrite z_gzfwrite -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# define uncompress2 z_uncompress2 -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -#ifdef Z_SOLO - typedef unsigned long z_size_t; -#else -# define z_longlong long long -# if defined(NO_SIZE_T) - typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include - typedef size_t z_size_t; -# else - typedef unsigned long z_size_t; -# endif -# undef z_longlong -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/ModelicaExternalC/C-Sources/zlib/zlib.h b/ModelicaExternalC/C-Sources/zlib/zlib.h deleted file mode 100644 index c02def7f8..000000000 --- a/ModelicaExternalC/C-Sources/zlib/zlib.h +++ /dev/null @@ -1,1912 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.11, January 15th, 2017 - - Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.11" -#define ZLIB_VERNUM 0x12b0 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 11 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip and raw deflate streams in - memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in the case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte will go here */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text - for deflate, or the decoding state for inflate */ - uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. In that case, zlib is thread-safe. When zalloc and zfree are - Z_NULL on entry to the initialization function, they are set to internal - routines that use the standard library functions malloc() and free(). - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use by the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field for deflate() */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary. Some output may be provided even if - flush is zero. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more output - in that case. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed - codes block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this - function must be called again with Z_FINISH and more output space (updated - avail_out) but no more input data, until it returns with Z_STREAM_END or an - error. After deflate has returned Z_STREAM_END, the only possible operations - on the stream are deflateReset or deflateEnd. - - Z_FINISH can be used in the first deflate call after deflateInit if all the - compression is to be done in a single step. In order to complete in one - call, avail_out must be at least the value returned by deflateBound (see - below). Then deflate is guaranteed to return Z_STREAM_END. If not enough - output space is provided, deflate will not return Z_STREAM_END, and it must - be called again as described above. - - deflate() sets strm->adler to the Adler-32 checksum of all input read - so far (that is, total_in bytes). If a gzip stream is being generated, then - strm->adler will be the CRC-32 checksum of the input read so far. (See - deflateInit2 below.) - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is - considered binary. This field is only for information purposes and does not - affect the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL or the state was inadvertently written over - by the application), or Z_BUF_ERROR if no progress is possible (for example - avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and - deflate() can be called again with more input and more output space to - continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. In the current version of inflate, the provided input is not - read or consumed. The allocation of a sliding window will be deferred to - the first call of inflate (if the decompression does not complete on the - first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression. - Actual decompression will be done by inflate(). So next_in, and avail_in, - next_out, and avail_out are unused and unchanged. The current - implementation of inflateInit() does not process any header information -- - that is deferred until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), then next_in and avail_in are updated - accordingly, and processing will resume at this point for the next call of - inflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. If the - caller of inflate() does not provide both available input and available - output space, it is possible that there will be no progress made. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - To assist in this, on return inflate() always sets strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed Adler-32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained unless inflateGetHeader() is used. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - produced so far. The CRC-32 is checked against the gzip trailer, as is the - uncompressed length, modulo 2^32. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value, in which case strm->msg points to a string with a more specific - error), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL, or the state was inadvertently written over - by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR - if no progress was possible or if there was not enough room in the output - buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is to be attempted. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state - was inconsistent. -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute a check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to the appropriate value, - if the operating system was determined at compile time. If a gzip stream is - being written, strm->adler is a CRC-32 instead of an Adler-32. - - For raw deflate or gzip encoding, a request for a 256-byte window is - rejected as invalid, since only the zlib header provides a means of - transmitting the window size to the decompressor. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the Adler-32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler-32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - Adler-32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by deflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If deflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similarly, if dictLength is Z_NULL, then it is not set. - - deflateGetDictionary() may return a length less than the window size, even - when more than the window size in input has been provided. It may return up - to 258 bytes less in that case, due to how zlib's implementation of deflate - manages the sliding window and lookahead for matches, where matches can be - up to 258 bytes long. If the application needs the last window-size bytes of - input, then that would need to be saved by the application outside of zlib. - - deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2(). This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the - strategy is changed, and if any input has been consumed in a previous - deflate() call, then the input available so far is compressed with the old - level and strategy using deflate(strm, Z_BLOCK). There are three approaches - for the compression levels 0, 1..3, and 4..9 respectively. The new level - and strategy will take effect at the next call of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not - take effect. In this case, deflateParams() can be called again with the - same parameters and more output space to try again. - - In order to assure a change in the parameters on the first try, the - deflate stream should be flushed using deflate() with Z_BLOCK or other flush - request until strm.avail_out is not zero, before calling deflateParams(). - Then no more input data should be provided before the deflateParams() call. - If this is done, the old level and strategy will be applied to the data - compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). - - deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression of the - available input data before a change in the strategy or approach. Note that - in the case of a Z_BUF_ERROR, the parameters are not changed. A return - value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be - retried with more output space. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an Adler-32 or a CRC-32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will not automatically decode concatenated gzip streams. - inflate() will return Z_STREAM_END at the end of the gzip stream. The state - would need to be reset to continue decoding a subsequent gzip stream. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler-32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler-32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similarly, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. If the window size is changed, then the - memory allocated for the window is freed, and the window will be reallocated - by inflate() if needed. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above, or -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the default - behavior of inflate(), which expects a zlib header and trailer around the - deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero -- buf is ignored in that - case -- and inflateBack() will return a buffer error. inflateBack() will - call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. - out() should return zero on success, or non-zero on failure. If out() - returns non-zero, inflateBack() will return with an error. Neither in() nor - out() are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: ZLIB_DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed data. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed data. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); -/* - Same as uncompress, except that sourceLen is a pointer, where the - length of the source is *sourceLen. On return, *sourceLen is the number of - source bytes consumed. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Three times that size in buffer space is allocated. A larger buffer - size of, for example, 64K or 128K bytes will noticeably increase the speed - of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. Previously provided - data is flushed before the parameter change. - - gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not - opened for writing, Z_ERRNO if there is an error writing the flushed data, - or Z_MEM_ERROR if there is a memory allocation error. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. If len is too large to fit in an int, - then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. -*/ - -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); -/* - Read up to nitems items of size size from file to buf, otherwise operating - as gzread() does. This duplicates the interface of stdio's fread(), with - size_t request and return types. If the library defines size_t, then - z_size_t is identical to size_t. If not, then z_size_t is an unsigned - integer type that can contain a pointer. - - gzfread() returns the number of full items read of size size, or zero if - the end of the file was reached and a full item could not be read, or if - there was an error. gzerror() must be consulted if zero is returned in - order to determine if there was an error. If the multiplication of size and - nitems overflows, i.e. the product does not fit in a z_size_t, then nothing - is read, zero is returned, and the error state is set to Z_STREAM_ERROR. - - In the event that the end of file is reached and only a partial item is - available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevetheless read into buf - and the end-of-file flag is set. The length of the partial item read is not - provided, but could be inferred from the result of gztell(). This behavior - is the same as the behavior of fread() implementations in common libraries, - but it prevents the direct use of gzfread() to read a concurrently written - file, reseting and retrying on end-of-file, when size is not 1. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); -/* - gzfwrite() writes nitems items of size size from buf to file, duplicating - the interface of stdio's fwrite(), with size_t request and return types. If - the library defines size_t, then z_size_t is identical to size_t. If not, - then z_size_t is an unsigned integer type that can contain a pointer. - - gzfwrite() returns the number of full items written of size size, or zero - if there was an error. If the multiplication of size and nitems overflows, - i.e. the product does not fit in a z_size_t, then nothing is written, zero - is returned, and the error state is set to Z_STREAM_ERROR. -*/ - -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or a negative zlib error code in case - of error. The number of uncompressed bytes written is limited to 8191, or - one less than the buffer size given to gzbuffer(). The caller should assure - that this limit is not exceeded. If it is exceeded, then gzprintf() will - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. - This can be determined using zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatenated gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as adler32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as crc32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#ifdef Z_PREFIX_SET -# define z_deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define z_inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#else -# define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#endif - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - -#endif /* !Z_SOLO */ - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); -# endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/ModelicaExternalC/C-Sources/zlib/zutil.c b/ModelicaExternalC/C-Sources/zlib/zutil.c deleted file mode 100644 index a76c6b0c7..000000000 --- a/ModelicaExternalC/C-Sources/zlib/zutil.c +++ /dev/null @@ -1,325 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2017 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" -#ifndef Z_SOLO -# include "gzguts.h" -#endif - -z_const char * const z_errmsg[10] = { - (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ - (z_const char *)"stream end", /* Z_STREAM_END 1 */ - (z_const char *)"", /* Z_OK 0 */ - (z_const char *)"file error", /* Z_ERRNO (-1) */ - (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ - (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ - (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ - (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ - (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ - (z_const char *)"" -}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef ZLIB_DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef ZLIB_DEBUG -#include -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifndef Z_SOLO - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf; - ulg bsize = (ulg)items*size; - - (void)opaque; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - int n; - - (void)opaque; - - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) -{ - (void)opaque; - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - (void)opaque; - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - (void)opaque; - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - (void)opaque; - free(ptr); -} - -#endif /* MY_ZCALLOC */ - -#endif /* !Z_SOLO */ diff --git a/ModelicaExternalC/C-Sources/zlib/zutil.h b/ModelicaExternalC/C-Sources/zlib/zutil.h deleted file mode 100644 index b079ea6a8..000000000 --- a/ModelicaExternalC/C-Sources/zlib/zutil.h +++ /dev/null @@ -1,271 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include -#endif - -#ifdef Z_SOLO - typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 1 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 2 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef __370__ -# if __TARGET_LIB__ < 0x20000000 -# define OS_CODE 4 -# elif __TARGET_LIB__ < 0x40000000 -# define OS_CODE 11 -# else -# define OS_CODE 8 -# endif -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 5 -#endif - -#ifdef OS2 -# define OS_CODE 6 -# if defined(M_I86) && !defined(Z_SOLO) -# include -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif -#endif - -#ifdef __acorn -# define OS_CODE 13 -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) -# define OS_CODE 10 -#endif - -#ifdef _BEOS_ -# define OS_CODE 16 -#endif - -#ifdef __TOS_OS400__ -# define OS_CODE 18 -#endif - -#ifdef __APPLE__ -# define OS_CODE 19 -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - -#if defined(__BORLANDC__) && !defined(MSDOS) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && \ - (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 3 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(pyr) || defined(Z_SOLO) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef ZLIB_DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -#ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); -#endif - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -/* Reverse the bytes in a 32-bit value */ -#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -#endif /* ZUTIL_H */ diff --git a/ModelicaExternalC/CMakeLists.txt b/ModelicaExternalC/CMakeLists.txt deleted file mode 100644 index 83a1b69a5..000000000 --- a/ModelicaExternalC/CMakeLists.txt +++ /dev/null @@ -1,81 +0,0 @@ - -cmake_minimum_required(VERSION 3.14) -project(OMModelicaExternalC) - - -# zlib -# We have decided to use zlib from here. We could have used the system zlib. However, -# modelica annotations request for "zlib" while the system zlib is OFTEN (but not always) called "libz" -# which means it should be used as "z". We can modify the annotations to use "z" but then -# it will be the same issue on systems that call it "zlib". So we need to find a solution. -# Originally I was creating a sym link to the system zlib in our lib directories. However, -# that might be confusing for others. So it might be better to explicitly -# build it and use it from here. The one advantage of this is that we can compile it with -fpic so -# that we can link it into our static FMUs. -file(GLOB libzlib_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/C-Sources/zlib/*.c) -add_library(zlib STATIC ${libzlib_SOURCES}) - -target_include_directories(zlib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/C-Sources/zlib) - -install(TARGETS zlib) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/C-Sources/zlib/zlib.h - ${CMAKE_CURRENT_SOURCE_DIR}/C-Sources/zlib/zconf.h - TYPE INCLUDE) - - - -# ModelicaExternalC -set(libModelicaExternalC_SOURCES C-Sources/ModelicaFFT.c - C-Sources/ModelicaInternal.c - C-Sources/ModelicaRandom.c - C-Sources/ModelicaStrings.c) -add_library(ModelicaExternalC STATIC ${libModelicaExternalC_SOURCES}) - -target_link_libraries(ModelicaExternalC PUBLIC m) - - -# ModelicaMatIO -set(libModelicaMatIO_SOURCES C-Sources/ModelicaMatIO.c C-Sources/snprintf.c) -add_library(ModelicaMatIO STATIC ${libModelicaMatIO_SOURCES}) - -target_compile_definitions(ModelicaMatIO PRIVATE HAVE_ZLIB) -target_link_libraries(ModelicaMatIO PUBLIC zlib) - -# find_package(ZLIB) -# if(ZLIB_FOUND) -# target_link_libraries(ModelicaMatIO PUBLIC ZLIB::ZLIB) -# target_compile_definitions(ModelicaMatIO PRIVATE HAVE_ZLIB) -# endif() - -# find_package(HDF5) -# if(HDF5_FOUND) -# target_include_directories(ModelicaMatIO PRIVATE ${HDF5_INCLUDE_DIRS}) -# target_link_libraries(ModelicaMatIO PUBLIC ${HDF5_LIBRARIES}) -# target_compile_definitions(ModelicaMatIO PRIVATE HAVE_HDF5) -# endif() - - -# ModelicaIO -set(libModelicaIO_SOURCES C-Sources/ModelicaIO.c) -add_library(ModelicaIO STATIC ${libModelicaIO_SOURCES}) - -target_link_libraries(ModelicaIO PUBLIC ModelicaMatIO) - - - -# ModelicaStandardTables -set(ModelicaStandardTables_SOURCES C-Sources/ModelicaStandardTables.c - C-Sources/ModelicaStandardTablesUsertab.c) -add_library(ModelicaStandardTables STATIC ${ModelicaStandardTables_SOURCES}) - -# This seems to be needed. Otherwise we get undefined referenes to function 'usertab' -target_compile_definitions(ModelicaStandardTables PRIVATE -DDUMMY_FUNCTION_USERTAB) - -target_link_libraries(ModelicaStandardTables INTERFACE ModelicaMatIO) -target_link_libraries(ModelicaStandardTables PUBLIC m) - - -install(TARGETS ModelicaExternalC - ModelicaMatIO - ModelicaIO - ModelicaStandardTables)