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)