Makefile.fetch                                      |    1 
 RepositoryExternal.mk                               |   17 +++
 bin/oss-fuzz-setup.sh                               |    1 
 config_host.mk.in                                   |    3 
 configure.ac                                        |   51 ++++++++++
 distro-configs/CPLinux-LOKit.conf                   |    1 
 distro-configs/Jenkins/LibreOfficeLinuxUpdater.conf |    1 
 distro-configs/LibreOfficeLinux.conf                |    1 
 distro-configs/LibreOfficeOnline.conf               |    1 
 distro-configs/LibreOfficeOpenBSD.conf              |    1 
 download.lst                                        |    5 +
 external/Module_external.mk                         |    1 
 external/zstd/Makefile                              |   14 ++
 external/zstd/Module_zstd.mk                        |   17 +++
 external/zstd/StaticLibrary_zstd.mk                 |   41 ++++++++
 external/zstd/UnpackedTarball_zstd.mk               |   14 ++
 include/package/InflateZstd.hxx                     |   48 ++++++++++
 package/Library_package2.mk                         |    3 
 package/inc/InflaterBytesZstd.hxx                   |   43 +++++++++
 package/source/zipapi/InflateZstd.cxx               |   94 ++++++++++++++++++++
 package/source/zipapi/InflaterBytesZstd.cxx         |   82 +++++++++++++++++
 21 files changed, 440 insertions(+)

New commits:
commit b410749d30ed167f5bf0da6491d72e55f596cd41
Author:     Akshay Kumar Dubey <[email protected]>
AuthorDate: Wed Apr 16 02:05:16 2025 +0530
Commit:     Caolán McNamara <[email protected]>
CommitDate: Thu May 1 12:18:19 2025 +0200

    tdf#137308 - Add zstd build support and decompression classes
    
    Integrate build system support for the Zstandard (zstd) library and
    implement the corresponding C++ decompression stream classes, enabling
    future use of zstd-compressed streams in ZIP packages.
    
    Build System (Part 2a):
    - Add `--with-system-zstd=[yes|no|auto]` configure option.
    - Implement system library checks (`zstd.h`, `libzstd`) in configure.ac.
    - Define rules (`external/zstd/*`) for downloading and building the
      internal zstd static library (decompression components only).
    - Set up necessary CFLAGS/LIBS via configure.ac and config_host.mk.in.
    - Configure linking via RepositoryExternal.mk (`gb_LinkTarget__use_zstd`).
    - Update auxiliary files (download.lst, distro-configs, etc.).
    
    C++ Implementation (Part 2b):
    - Implement `InflateZstd` (in `include/package`) and `InflaterBytesZstd`
      (in `package/inc`) inheriting from `Inflater`/`InflaterBytes`.
    - Use the zstd streaming API (`ZSTD_decompressStream`) following the
      existing single-call pattern established by the zlib implementation.
    - Manage context (`ZSTD_DCtx`) and input buffer (`ZSTD_inBuffer`) state.
    - Handle errors, stream completion (`ret == 0`), and input truncation.
    - Add new classes to `package/Library_package2.mk` build.
    
    This completes the infrastructure for zstd decompression support.
    The next step (Part 2c) involves adding logic to select the
    appropriate Inflater based on the ZIP entry's compression method ID.
    
    Change-Id: Ia673f3f19b6a751ba5225394fcf8c3f145c4ae63
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184243
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/Makefile.fetch b/Makefile.fetch
index f96fc16f8926..7c8d45f07a01 100644
--- a/Makefile.fetch
+++ b/Makefile.fetch
@@ -240,6 +240,7 @@ $(WORKDIR)/download: $(BUILDDIR)/config_$(gb_Side).mk 
$(SRCDIR)/download.lst $(S
                $(call fetch_Optional,WPS,WPS_TARBALL) \
                $(call fetch_Optional,XSLTML,XSLTML_TARBALL) \
                $(call fetch_Optional,ZLIB,ZLIB_TARBALL) \
+               $(call fetch_Optional,ZSTD,ZSTD_TARBALL) \
                $(call fetch_Optional,ZMF,ZMF_TARBALL) \
        ,$(call 
fetch_Download_item,https://dev-www.libreoffice.org/src,$(item)))
        $(foreach item, \
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index ff4c86ba3b33..f16521c50d7d 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -409,6 +409,23 @@ endef
 
 endif # SYSTEM_ZLIB
 
+ifneq ($(SYSTEM_ZSTD),)
+  define gb_LinkTarget__use_zstd
+    $(call gb_LinkTarget_add_libs,$(1),-lzstd)
+  endef
+
+  gb_ExternalProject__use_zstd :=
+else
+  define gb_LinkTarget__use_zstd
+    $(call gb_LinkTarget_set_include,$(1),$(ZSTD_CFLAGS) $$(INCLUDE))
+    $(call gb_LinkTarget_use_static_libraries,$(1),zstd)
+  endef
+
+  define gb_ExternalProject__use_zstd
+    $(call gb_ExternalProject_use_static_libraries,$(1),zstd)
+  endef
+endif
+
 
 ifneq ($(SYSTEM_LIBJPEG),)
 
diff --git a/bin/oss-fuzz-setup.sh b/bin/oss-fuzz-setup.sh
index 565f972948e2..4df82dd0e050 100755
--- a/bin/oss-fuzz-setup.sh
+++ b/bin/oss-fuzz-setup.sh
@@ -53,6 +53,7 @@ curl --no-progress-meter -S \
     -C - -O https://dev-www.libreoffice.org/src/$ZMF_TARBALL \
     -C - -O https://dev-www.libreoffice.org/src/$PIXMAN_TARBALL \
     -C - -O https://dev-www.libreoffice.org/src/$ZLIB_TARBALL \
+    -C - -O https://dev-www.libreoffice.org/src/$ZSTD_TARBALL \
     -C - -O https://dev-www.libreoffice.org/src/$MDDS_TARBALL \
     -C - -O https://dev-www.libreoffice.org/src/$OPENSSL_TARBALL \
     -C - -O https://dev-www.libreoffice.org/src/$LANGTAGREG_TARBALL \
diff --git a/config_host.mk.in b/config_host.mk.in
index c210d78708a7..0a4d61f62875 100644
--- a/config_host.mk.in
+++ b/config_host.mk.in
@@ -736,6 +736,7 @@ SYSTEM_WPG=@SYSTEM_WPG@
 SYSTEM_WPS=@SYSTEM_WPS@
 SYSTEM_XMLSEC=@SYSTEM_XMLSEC@
 SYSTEM_ZLIB=@SYSTEM_ZLIB@
+SYSTEM_ZSTD=@SYSTEM_ZSTD@
 SYSTEM_ZMF=@SYSTEM_ZMF@
 export SYSTEMD_ESCAPE=@SYSTEMD_ESCAPE@
 export SYSTEMD_RUN=@SYSTEMD_RUN@
@@ -803,6 +804,8 @@ export XSLTPROC=@XSLTPROC@
 export XVFB_RUN=@XVFB_RUN@
 export ZLIB_CFLAGS=$(gb_SPACE)@ZLIB_CFLAGS@
 export ZLIB_LIBS=$(gb_SPACE)@ZLIB_LIBS@
+ZSTD_CFLAGS=$(gb_SPACE)@ZSTD_CFLAGS@
+ZSTD_LIBS=$(gb_SPACE)@ZSTD_LIBS@
 export ZMF_CFLAGS=$(gb_SPACE)@ZMF_CFLAGS@
 export ZMF_LIBS=$(gb_SPACE)@ZMF_LIBS@
 export GET_TASK_ALLOW_ENTITLEMENT=@GET_TASK_ALLOW_ENTITLEMENT@
diff --git a/configure.ac b/configure.ac
index 28364e612ee9..0bb64aabb9dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2439,6 +2439,11 @@ AC_ARG_WITH(system-zlib,
         [Use zlib already on system.]),,
     [with_system_zlib=auto])
 
+AC_ARG_WITH(system-zstd,
+    AS_HELP_STRING([--with-system-zstd=@<:@yes|no|auto@:>@],
+        [Use zstd already on system [default=auto].]),,
+    [with_system_zstd=auto])
+
 AC_ARG_WITH(system-jpeg,
     AS_HELP_STRING([--with-system-jpeg],
         [Use jpeg already on system.]),,
@@ -9857,6 +9862,52 @@ AC_SUBST(ZLIB_CFLAGS)
 AC_SUBST(ZLIB_LIBS)
 AC_SUBST(SYSTEM_ZLIB)
 
+dnl ===================================================================
+dnl Check for system zstd
+dnl ===================================================================
+
+if test "x$with_system_zstd" = "xauto"; then
+  case "$_os" in
+    WINNT) with_system_zstd="$with_system_libs" ;;  # follow system-libs on 
Windows
+    *)     with_system_zstd="$with_system_libs" ;;  # follow system-libs on 
Unix
+  esac
+fi
+
+AC_MSG_CHECKING([which zstd to use])
+case "$with_system_zstd" in
+  yes)
+    AC_MSG_RESULT([system])
+    SYSTEM_ZSTD=TRUE
+
+    AC_CHECK_HEADER([zstd.h], [],
+      [AC_MSG_ERROR([zstd.h not found. Install system zstd.])])
+
+    AC_CHECK_LIB([zstd], [ZSTD_createDStream],
+      [ ZSTD_LIBS="-lzstd"
+        ZSTD_CFLAGS="" ],
+      [ AC_MSG_ERROR([system zstd library not found or broken.]) ])
+    ;;
+
+  ""|no)
+    AC_MSG_RESULT([bundled])
+    SYSTEM_ZSTD=
+    ZSTD_LIBS=""
+    ZSTD_CFLAGS="-I\${WORKDIR}/UnpackedTarball/zstd/lib \
+                 -I\${WORKDIR}/UnpackedTarball/zstd/lib/common \
+                 -I\${WORKDIR}/UnpackedTarball/zstd/lib/decompress"
+    BUILD_TYPE="$BUILD_TYPE ZSTD"
+    ;;
+
+  *)
+    AC_MSG_ERROR([Invalid value for --with-system-zstd: $with_system_zstd])
+    ;;
+esac
+
+AC_SUBST(SYSTEM_ZSTD)
+AC_SUBST(ZSTD_LIBS)
+AC_SUBST(ZSTD_CFLAGS)
+AC_SUBST(BUILD_TYPE)
+
 dnl ===================================================================
 dnl Check for system jpeg
 dnl ===================================================================
diff --git a/distro-configs/CPLinux-LOKit.conf 
b/distro-configs/CPLinux-LOKit.conf
index 321cb967b217..ef2a8638c57a 100644
--- a/distro-configs/CPLinux-LOKit.conf
+++ b/distro-configs/CPLinux-LOKit.conf
@@ -6,6 +6,7 @@
 --with-system-dicts
 --with-myspell-dicts
 --with-system-zlib
+--with-system-zstd
 --disable-poppler
 --enable-cairo-rgba
 --without-system-cairo
diff --git a/distro-configs/Jenkins/LibreOfficeLinuxUpdater.conf 
b/distro-configs/Jenkins/LibreOfficeLinuxUpdater.conf
index d9af64650eff..726044dbca49 100644
--- a/distro-configs/Jenkins/LibreOfficeLinuxUpdater.conf
+++ b/distro-configs/Jenkins/LibreOfficeLinuxUpdater.conf
@@ -3,6 +3,7 @@
 --with-system-dicts
 --with-myspell-dicts
 --with-system-zlib
+--with-system-zstd
 --without-system-poppler
 --without-system-openssl
 --without-system-libpng
diff --git a/distro-configs/LibreOfficeLinux.conf 
b/distro-configs/LibreOfficeLinux.conf
index fba02d362d31..9d5b511db944 100644
--- a/distro-configs/LibreOfficeLinux.conf
+++ b/distro-configs/LibreOfficeLinux.conf
@@ -1,6 +1,7 @@
 --with-system-dicts
 --with-myspell-dicts
 --with-system-zlib
+--with-system-zstd
 --without-system-poppler
 --without-system-openssl
 --without-system-libpng
diff --git a/distro-configs/LibreOfficeOnline.conf 
b/distro-configs/LibreOfficeOnline.conf
index b22639232b71..73b21a1dc530 100644
--- a/distro-configs/LibreOfficeOnline.conf
+++ b/distro-configs/LibreOfficeOnline.conf
@@ -37,6 +37,7 @@
 --with-linker-hash-style=both
 --with-system-dicts
 --with-system-zlib
+--with-system-zstd
 --with-theme=colibre
 --without-branding
 --without-help
diff --git a/distro-configs/LibreOfficeOpenBSD.conf 
b/distro-configs/LibreOfficeOpenBSD.conf
index 2af93a64202a..6933487102fd 100644
--- a/distro-configs/LibreOfficeOpenBSD.conf
+++ b/distro-configs/LibreOfficeOpenBSD.conf
@@ -26,6 +26,7 @@
 --with-system-poppler
 --with-system-redland
 --with-system-zlib
+--with-system-zstd
 --with-vendor=The OpenBSD project
 --without-junit
 --without-system-libwpd
diff --git a/download.lst b/download.lst
index b1c058e0ab98..931bd94cdfff 100644
--- a/download.lst
+++ b/download.lst
@@ -680,6 +680,11 @@ ZLIB_TARBALL := zlib-1.3.1.tar.xz
 # three static lines
 # so that git cherry-pick
 # will not run into conflicts
+ZSTD_SHA256SUM := 
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3
+ZSTD_TARBALL := zstd-1.5.7.tar.gz
+# three static lines
+# so that git cherry-pick
+# will not run into conflicts
 ZMF_SHA256SUM := 
27051a30cb057fdb5d5de65a1f165c7153dc76e27fe62251cbb86639eb2caf22
 ZMF_TARBALL := libzmf-0.0.2.tar.xz
 # three static lines
diff --git a/external/Module_external.mk b/external/Module_external.mk
index 1d4c53139cac..6390a3a7d95b 100644
--- a/external/Module_external.mk
+++ b/external/Module_external.mk
@@ -101,6 +101,7 @@ $(eval $(call gb_Module_add_moduledirs,external,\
        $(call gb_Helper_optional,WPS,libwps) \
        $(call gb_Helper_optional,XSLTML,xsltml) \
        $(call gb_Helper_optional,ZLIB,zlib) \
+       $(call gb_Helper_optional,ZSTD,zstd) \
        $(call gb_Helper_optional,ZMF,libzmf) \
 ))
 
diff --git a/external/zstd/Makefile b/external/zstd/Makefile
new file mode 100644
index 000000000000..569ad8a0ba7a
--- /dev/null
+++ b/external/zstd/Makefile
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zstd/Module_zstd.mk b/external/zstd/Module_zstd.mk
new file mode 100644
index 000000000000..a31acb767fc7
--- /dev/null
+++ b/external/zstd/Module_zstd.mk
@@ -0,0 +1,17 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,zstd))
+
+$(eval $(call gb_Module_add_targets,zstd,\
+    StaticLibrary_zstd \
+    UnpackedTarball_zstd \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zstd/StaticLibrary_zstd.mk 
b/external/zstd/StaticLibrary_zstd.mk
new file mode 100644
index 000000000000..c7ca142dabd0
--- /dev/null
+++ b/external/zstd/StaticLibrary_zstd.mk
@@ -0,0 +1,41 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,zstd))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,zstd,zstd))
+
+$(eval $(call gb_StaticLibrary_set_warnings_disabled,zstd))
+
+$(eval $(call gb_StaticLibrary_set_include,zstd,\
+    -I$(gb_UnpackedTarball_workdir)/zstd/lib \
+    -I$(gb_UnpackedTarball_workdir)/zstd/lib/common \
+    -I$(gb_UnpackedTarball_workdir)/zstd/lib/decompress \
+    $$(INCLUDE) \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,zstd,\
+    UnpackedTarball/zstd/lib/common/entropy_common \
+    UnpackedTarball/zstd/lib/common/error_private \
+    UnpackedTarball/zstd/lib/common/fse_decompress \
+    UnpackedTarball/zstd/lib/common/xxhash \
+    UnpackedTarball/zstd/lib/common/zstd_common \
+    UnpackedTarball/zstd/lib/decompress/huf_decompress \
+    UnpackedTarball/zstd/lib/decompress/zstd_ddict \
+    UnpackedTarball/zstd/lib/decompress/zstd_decompress \
+    UnpackedTarball/zstd/lib/decompress/zstd_decompress_block \
+))
+
+$(eval $(call gb_StaticLibrary_add_cflags,zstd,-DZSTD_DISABLE_ASM))
+
+ifeq ($(ENABLE_DEBUG),TRUE)
+$(eval $(call gb_StaticLibrary_add_cflags,zstd,-DZSTD_DEBUG=1))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/zstd/UnpackedTarball_zstd.mk 
b/external/zstd/UnpackedTarball_zstd.mk
new file mode 100644
index 000000000000..7770ffe1add0
--- /dev/null
+++ b/external/zstd/UnpackedTarball_zstd.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,zstd))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,zstd,$(ZSTD_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/include/package/InflateZstd.hxx b/include/package/InflateZstd.hxx
new file mode 100644
index 000000000000..36cb0b15405c
--- /dev/null
+++ b/include/package/InflateZstd.hxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <memory>
+#include <package/Inflater.hxx>
+#include <zstd.h>
+#include <zstd_errors.h>
+
+namespace ZipUtils
+{
+class DLLPUBLIC_PACKAGE InflateZstd : public Inflater
+{
+private:
+    bool bFinished;
+    bool bNeedDict;
+    sal_Int32 nLastInflateError;
+    css::uno::Sequence<sal_Int8> sInBuffer;
+    ZSTD_DCtx* pDCtx;
+    ZSTD_inBuffer inBuffer;
+    bool bStreamInitialized;
+
+    sal_Int32 doInflateBytes(css::uno::Sequence<sal_Int8>& rBuffer, sal_Int32 
nNewOffset,
+                             sal_Int32 nNewLength);
+
+public:
+    explicit InflateZstd(bool bNoWrap = false);
+    virtual ~InflateZstd() override;
+
+    virtual void setInput(const css::uno::Sequence<sal_Int8>& rBuffer) 
override;
+    virtual bool needsDictionary() const override { return bNeedDict; }
+    virtual bool finished() const override { return bFinished; }
+    virtual sal_Int32 doInflateSegment(css::uno::Sequence<sal_Int8>& rBuffer, 
sal_Int32 nNewOffset,
+                                       sal_Int32 nNewLength) override;
+    virtual void end() override final;
+    virtual sal_Int32 getLastInflateError() const override { return 
nLastInflateError; }
+};
+
+} // namespace ZipUtils
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/package/Library_package2.mk b/package/Library_package2.mk
index a740d33fc757..bb7f36eb802f 100644
--- a/package/Library_package2.mk
+++ b/package/Library_package2.mk
@@ -43,6 +43,7 @@ $(eval $(call gb_Library_use_libraries,package2,\
 $(eval $(call gb_Library_use_externals,package2,\
        argon2 \
        zlib \
+       zstd \
 ))
 
 $(eval $(call gb_Library_add_exception_objects,package2,\
@@ -56,7 +57,9 @@ $(eval $(call gb_Library_add_exception_objects,package2,\
        package/source/zipapi/CRC32 \
        package/source/zipapi/Deflater \
        package/source/zipapi/InflaterBytesZlib \
+       package/source/zipapi/InflaterBytesZstd \
        package/source/zipapi/InflateZlib \
+       package/source/zipapi/InflateZstd \
        package/source/zipapi/sha1context \
        package/source/zipapi/ThreadedDeflater \
        package/source/zipapi/XBufferedThreadedStream \
diff --git a/package/inc/InflaterBytesZstd.hxx 
b/package/inc/InflaterBytesZstd.hxx
new file mode 100644
index 000000000000..96cf73baf5fe
--- /dev/null
+++ b/package/inc/InflaterBytesZstd.hxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <memory>
+#include <package/Inflater.hxx>
+#include <zstd.h>
+
+namespace ZipUtils
+{
+class DLLPUBLIC_PACKAGE InflaterBytesZstd : public InflaterBytes
+{
+private:
+    bool bFinished;
+    const sal_Int8* sInBuffer;
+    ZSTD_DCtx* pDCtx;
+    sal_Int32 nLastInflateError;
+    ZSTD_inBuffer inBuffer;
+    bool bStreamInitialized;
+
+    sal_Int32 doInflateBytes(sal_Int8* pOutBuffer, sal_Int32 nNewOffset, 
sal_Int32 nNewLength);
+
+public:
+    InflaterBytesZstd();
+    virtual ~InflaterBytesZstd() override;
+
+    virtual void setInput(const sal_Int8* pBuffer, sal_Int32 nLen) override;
+    virtual bool finished() const override { return bFinished; }
+    virtual sal_Int32 doInflateSegment(sal_Int8* pOutBuffer, sal_Int32 nBufLen,
+                                       sal_Int32 nNewOffset, sal_Int32 
nNewLength) override;
+    virtual void end() override final;
+};
+
+} // namespace ZipUtils
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/package/source/zipapi/InflateZstd.cxx 
b/package/source/zipapi/InflateZstd.cxx
new file mode 100644
index 000000000000..16638417c569
--- /dev/null
+++ b/package/source/zipapi/InflateZstd.cxx
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <package/InflateZstd.hxx>
+#include <string.h>
+
+using namespace com::sun::star::uno;
+using namespace ZipUtils;
+
+InflateZstd::InflateZstd(bool)
+    : bFinished(false)
+    , bNeedDict(false)
+    , nLastInflateError(0)
+    , pDCtx(ZSTD_createDCtx())
+    , bStreamInitialized(false)
+{
+    if (!pDCtx)
+    {
+        nLastInflateError = 
static_cast<sal_Int32>(ZSTD_error_memory_allocation);
+    }
+    inBuffer = { nullptr, 0, 0 };
+}
+
+InflateZstd::~InflateZstd() { end(); }
+
+void InflateZstd::setInput(const Sequence<sal_Int8>& rBuffer)
+{
+    if (!pDCtx)
+    {
+        bStreamInitialized = false;
+        return;
+    }
+    sInBuffer = rBuffer;
+    inBuffer.src = sInBuffer.getConstArray();
+    inBuffer.size = sInBuffer.getLength();
+    inBuffer.pos = 0;
+    bStreamInitialized = true;
+}
+
+sal_Int32 InflateZstd::doInflateSegment(Sequence<sal_Int8>& rBuffer, sal_Int32 
nNewOffset,
+                                        sal_Int32 nNewLength)
+{
+    if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > 
rBuffer.getLength())
+        return 0;
+
+    return doInflateBytes(rBuffer, nNewOffset, nNewLength);
+}
+
+void InflateZstd::end()
+{
+    if (pDCtx)
+    {
+        ZSTD_freeDCtx(pDCtx);
+        pDCtx = nullptr;
+    }
+    bStreamInitialized = false;
+    inBuffer = { nullptr, 0, 0 };
+}
+
+sal_Int32 InflateZstd::doInflateBytes(Sequence<sal_Int8>& rBuffer, sal_Int32 
nNewOffset,
+                                      sal_Int32 nNewLength)
+{
+    if (bFinished)
+    {
+        return 0;
+    }
+    if (!pDCtx || !bStreamInitialized)
+    {
+        nLastInflateError = 1;
+        return 0;
+    }
+    nLastInflateError = 0;
+    ZSTD_outBuffer outBuffer
+        = { rBuffer.getArray() + nNewOffset, static_cast<size_t>(nNewLength), 
0 };
+    size_t ret = ZSTD_decompressStream(pDCtx, &outBuffer, &inBuffer);
+    if (ZSTD_isError(ret))
+    {
+        nLastInflateError = static_cast<sal_Int32>(ret);
+        ZSTD_DCtx_reset(pDCtx, ZSTD_reset_session_only);
+        return 0;
+    }
+    if (ret == 0)
+        bFinished = true;
+
+    return static_cast<sal_Int32>(outBuffer.pos);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/package/source/zipapi/InflaterBytesZstd.cxx 
b/package/source/zipapi/InflaterBytesZstd.cxx
new file mode 100644
index 000000000000..4236a58207df
--- /dev/null
+++ b/package/source/zipapi/InflaterBytesZstd.cxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <InflaterBytesZstd.hxx>
+#include <string.h>
+
+using namespace ZipUtils;
+
+InflaterBytesZstd::InflaterBytesZstd()
+    : bFinished(false)
+    , sInBuffer(nullptr)
+    , pDCtx(ZSTD_createDCtx())
+    , nLastInflateError(0)
+    , bStreamInitialized(false)
+{
+    inBuffer = { nullptr, 0, 0 };
+}
+
+InflaterBytesZstd::~InflaterBytesZstd() { end(); }
+
+void InflaterBytesZstd::setInput(const sal_Int8* rBuffer, sal_Int32 nBufLen)
+{
+    sInBuffer = rBuffer;
+    inBuffer.src = sInBuffer;
+    inBuffer.size = nBufLen;
+    inBuffer.pos = 0;
+    bStreamInitialized = true;
+}
+
+sal_Int32 InflaterBytesZstd::doInflateSegment(sal_Int8* pOutBuffer, sal_Int32 
nBufLen,
+                                              sal_Int32 nNewOffset, sal_Int32 
nNewLength)
+{
+    if (nNewOffset < 0 || nNewLength < 0 || nNewOffset + nNewLength > nBufLen)
+        return 0;
+
+    return doInflateBytes(pOutBuffer, nNewOffset, nNewLength);
+}
+
+void InflaterBytesZstd::end()
+{
+    if (pDCtx)
+    {
+        ZSTD_freeDCtx(pDCtx);
+        pDCtx = nullptr;
+    }
+    bStreamInitialized = false;
+    inBuffer = { nullptr, 0, 0 };
+}
+
+sal_Int32 InflaterBytesZstd::doInflateBytes(sal_Int8* pOutBuffer, sal_Int32 
nNewOffset,
+                                            sal_Int32 nNewLength)
+{
+    if (!pDCtx || !bStreamInitialized)
+        return 0;
+
+    ZSTD_outBuffer outBuffer = { pOutBuffer + nNewOffset, 
static_cast<size_t>(nNewLength), 0 };
+    size_t ret = ZSTD_decompressStream(pDCtx, &outBuffer, &inBuffer);
+    if (ZSTD_isError(ret))
+    {
+        nLastInflateError = static_cast<sal_Int32>(ret);
+        ZSTD_DCtx_reset(pDCtx, ZSTD_reset_session_only);
+        return 0;
+    }
+    if (ret != 0)
+    {
+        ZSTD_DCtx_reset(pDCtx, ZSTD_reset_session_only);
+        return static_cast<sal_Int32>(outBuffer.pos);
+    }
+    if (ret == 0)
+        bFinished = true;
+    nLastInflateError = 0;
+
+    return static_cast<sal_Int32>(outBuffer.pos);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */

Reply via email to