mirror of
https://github.com/PCSX2/xz.git
synced 2026-02-06 20:31:17 +01:00
Compare commits
71 Commits
v5.1.2alph
...
v5.1.3alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae222fe980 | ||
|
|
2193837a6a | ||
|
|
ed48e75e27 | ||
|
|
841da0352d | ||
|
|
56feb8665b | ||
|
|
ba413da1d5 | ||
|
|
0cd45fc2bc | ||
|
|
97bb38712f | ||
|
|
fef0c6b410 | ||
|
|
8083e03291 | ||
|
|
6b44b4a775 | ||
|
|
ae0ab74a88 | ||
|
|
72975df6c8 | ||
|
|
1c2b6e7e83 | ||
|
|
124eb69c78 | ||
|
|
eada8a875c | ||
|
|
be0100d01c | ||
|
|
416729e2d7 | ||
|
|
16581080e5 | ||
|
|
3e2b198ba3 | ||
|
|
dee6ad3d59 | ||
|
|
fa381acaf9 | ||
|
|
ea00545bea | ||
|
|
736903c64b | ||
|
|
24edf8d807 | ||
|
|
c0627b3fce | ||
|
|
1936718bb3 | ||
|
|
a37ae8b5eb | ||
|
|
cdba9ddd87 | ||
|
|
e61a5c95da | ||
|
|
9dc319eabb | ||
|
|
3541bc79d0 | ||
|
|
78673a08be | ||
|
|
a616fdad34 | ||
|
|
4a08a6e4c6 | ||
|
|
b790b435da | ||
|
|
84d2da6c9d | ||
|
|
9376f5f8f7 | ||
|
|
b7e200d7bd | ||
|
|
46540e4c10 | ||
|
|
ebb501ec73 | ||
|
|
c09e91dd23 | ||
|
|
eb6ca9854b | ||
|
|
0c0a1947e6 | ||
|
|
2fcda89939 | ||
|
|
97379c5ea7 | ||
|
|
8957c58609 | ||
|
|
ed886e1a92 | ||
|
|
5019413a05 | ||
|
|
5ea900cb5a | ||
|
|
bb117fffa8 | ||
|
|
e572e123b5 | ||
|
|
b465da5988 | ||
|
|
9e6dabcf22 | ||
|
|
e7b424d267 | ||
|
|
2ebbb994e3 | ||
|
|
4c7e28705f | ||
|
|
db5c1817fa | ||
|
|
65536214a3 | ||
|
|
3d93b63549 | ||
|
|
ab22562066 | ||
|
|
f3c1ec69d9 | ||
|
|
d8eaf9d827 | ||
|
|
96e08902b0 | ||
|
|
3778db1be5 | ||
|
|
d625c7cf82 | ||
|
|
0b09d266cc | ||
|
|
d6e0b23d46 | ||
|
|
19de545d86 | ||
|
|
672eccf57c | ||
|
|
cafb523ada |
39
INSTALL
39
INSTALL
@@ -307,16 +307,37 @@ XZ Utils Installation
|
||||
the amount of RAM on the operating system you use. See
|
||||
src/common/tuklib_physmem.c for details.
|
||||
|
||||
--disable-threads
|
||||
Disable threading support. This makes some things
|
||||
thread-unsafe, meaning that if multithreaded application
|
||||
calls liblzma functions from more than one thread,
|
||||
something bad may happen.
|
||||
--enable-threads=METHOD
|
||||
Threading support is enabled by default so normally there
|
||||
is no need to specify this option.
|
||||
|
||||
Use this option if threading support causes you trouble,
|
||||
or if you know that you will use liblzma only from
|
||||
single-threaded applications and want to avoid dependency
|
||||
on libpthread.
|
||||
Supported values for METHOD:
|
||||
|
||||
yes Autodetect the threading method. If none
|
||||
is found, configure will give an error.
|
||||
|
||||
posix Use POSIX pthreads. This is the default
|
||||
except on Windows outside Cygwin.
|
||||
|
||||
win95 Use Windows 95 compatible threads. This
|
||||
is compatible with Windows XP and later
|
||||
too. This is the default for 32-bit x86
|
||||
Windows builds. The `win95' threading is
|
||||
incompatible with --enable-small.
|
||||
|
||||
vista Use Windows Vista compatible threads. The
|
||||
resulting binaries won't run on Windows XP
|
||||
or older. This is the default for Windows
|
||||
excluding 32-bit x86 builds (that is, on
|
||||
x86-64 the default is `vista').
|
||||
|
||||
no Disable threading support. This is the
|
||||
same as using --disable-threads.
|
||||
NOTE: If combined with --enable-small, the
|
||||
resulting liblzma won't be thread safe,
|
||||
that is, if a multi-threaded application
|
||||
calls any liblzma functions from more than
|
||||
one thread, something bad may happen.
|
||||
|
||||
--enable-symbol-versions
|
||||
Use symbol versioning for liblzma. This is enabled by
|
||||
|
||||
@@ -47,6 +47,7 @@ EXTRA_DIST = \
|
||||
extra \
|
||||
dos \
|
||||
windows \
|
||||
macosx \
|
||||
autogen.sh \
|
||||
Doxyfile.in \
|
||||
COPYING.GPLv2 \
|
||||
|
||||
87
NEWS
87
NEWS
@@ -2,6 +2,41 @@
|
||||
XZ Utils Release Notes
|
||||
======================
|
||||
|
||||
5.1.3alpha (2013-10-26)
|
||||
|
||||
* All fixes from 5.0.5
|
||||
|
||||
* liblzma:
|
||||
|
||||
- Fixed a deadlock in the threaded encoder.
|
||||
|
||||
- Made the uses of lzma_allocator const correct.
|
||||
|
||||
- Added lzma_block_uncomp_encode() to create uncompressed
|
||||
.xz Blocks using LZMA2 uncompressed chunks.
|
||||
|
||||
- Added support for native threads on Windows and the ability
|
||||
to detect the number of CPU cores.
|
||||
|
||||
* xz:
|
||||
|
||||
- Fixed a race condition in the signal handling. It was
|
||||
possible that e.g. the first SIGINT didn't make xz exit
|
||||
if reading or writing blocked and one had bad luck. The fix
|
||||
is non-trivial, so as of writing it is unknown if it will be
|
||||
backported to the v5.0 branch.
|
||||
|
||||
- Made the progress indicator work correctly in threaded mode.
|
||||
|
||||
- Threaded encoder now works together with --block-list=SIZES.
|
||||
|
||||
- Added preliminary support for --flush-timeout=TIMEOUT.
|
||||
It can be useful for (somewhat) real-time streaming. For
|
||||
now the decompression side has to be done with something
|
||||
else than the xz tool due to how xz does buffering, but this
|
||||
should be fixed.
|
||||
|
||||
|
||||
5.1.2alpha (2012-07-04)
|
||||
|
||||
* All fixes from 5.0.3 and 5.0.4
|
||||
@@ -86,6 +121,58 @@ XZ Utils Release Notes
|
||||
experimental and may change before it gets into a stable release.
|
||||
|
||||
|
||||
5.0.5 (2013-06-30)
|
||||
|
||||
* lzmadec and liblzma's lzma_alone_decoder(): Support decompressing
|
||||
.lzma files that have less common settings in the headers
|
||||
(dictionary size other than 2^n or 2^n + 2^(n-1), or uncompressed
|
||||
size greater than 256 GiB). The limitations existed to avoid false
|
||||
positives when detecting .lzma files. The lc + lp <= 4 limitation
|
||||
still remains since liblzma's LZMA decoder has that limitation.
|
||||
|
||||
NOTE: xz's .lzma support or liblzma's lzma_auto_decoder() are NOT
|
||||
affected by this change. They still consider uncommon .lzma headers
|
||||
as not being in the .lzma format. Changing this would give way too
|
||||
many false positives.
|
||||
|
||||
* xz:
|
||||
|
||||
- Interaction of preset and custom filter chain options was
|
||||
made less illogical. This affects only certain less typical
|
||||
uses cases so few people are expected to notice this change.
|
||||
|
||||
Now when a custom filter chain option (e.g. --lzma2) is
|
||||
specified, all preset options (-0 ... -9, -e) earlier are on
|
||||
the command line are completely forgotten. Similarly, when
|
||||
a preset option is specified, all custom filter chain options
|
||||
earlier on the command line are completely forgotten.
|
||||
|
||||
Example 1: "xz -9 --lzma2=preset=5 -e" is equivalent to "xz -e"
|
||||
which is equivalent to "xz -6e". Earlier -e didn't put xz back
|
||||
into preset mode and thus the example command was equivalent
|
||||
to "xz --lzma2=preset=5".
|
||||
|
||||
Example 2: "xz -9e --lzma2=preset=5 -7" is equivalent to
|
||||
"xz -7". Earlier a custom filter chain option didn't make
|
||||
xz forget the -e option so the example was equivalent to
|
||||
"xz -7e".
|
||||
|
||||
- Fixes and improvements to error handling.
|
||||
|
||||
- Various fixes to the man page.
|
||||
|
||||
* xzless: Fixed to work with "less" versions 448 and later.
|
||||
|
||||
* xzgrep: Made -h an alias for --no-filename.
|
||||
|
||||
* Include the previously missing debug/translation.bash which can
|
||||
be useful for translators.
|
||||
|
||||
* Include a build script for Mac OS X. This has been in the Git
|
||||
repository since 2010 but due to a mistake in Makefile.am the
|
||||
script hasn't been included in a release tarball before.
|
||||
|
||||
|
||||
5.0.4 (2012-06-22)
|
||||
|
||||
* liblzma:
|
||||
|
||||
4
README
4
README
@@ -210,8 +210,8 @@ XZ Utils
|
||||
# <Edit the .po file in the po directory.>
|
||||
make -C po update-po
|
||||
make install
|
||||
bash debug/translations.bash | less
|
||||
bash debug/translations.bash | less -S # For --list outputs
|
||||
bash debug/translation.bash | less
|
||||
bash debug/translation.bash | less -S # For --list outputs
|
||||
|
||||
Repeat the above as needed (no need to re-run configure though).
|
||||
|
||||
|
||||
8
THANKS
8
THANKS
@@ -6,6 +6,7 @@ Some people have helped more, some less, but nevertheless everyone's help
|
||||
has been important. :-) In alphabetical order:
|
||||
- Mark Adler
|
||||
- H. Peter Anvin
|
||||
- Jeff Bastian
|
||||
- Nelson H. F. Beebe
|
||||
- Karl Berry
|
||||
- Anders F. Björklund
|
||||
@@ -32,12 +33,15 @@ has been important. :-) In alphabetical order:
|
||||
- Jason Gorski
|
||||
- Juan Manuel Guerrero
|
||||
- Joachim Henke
|
||||
- Christian Hesse
|
||||
- Peter Ivanov
|
||||
- Jouk Jansen
|
||||
- Per Øyvind Karlsen
|
||||
- Thomas Klausner
|
||||
- Richard Koch
|
||||
- Ville Koskinen
|
||||
- Jan Kratochvil
|
||||
- Christian Kujau
|
||||
- Stephan Kulow
|
||||
- Peter Lawler
|
||||
- Hin-Tak Leung
|
||||
@@ -49,6 +53,7 @@ has been important. :-) In alphabetical order:
|
||||
- Gregory Margo
|
||||
- Jim Meyering
|
||||
- Arkadiusz Miskiewicz
|
||||
- Conley Moorhous
|
||||
- Rafał Mużyło
|
||||
- Adrien Nader
|
||||
- Hongbo Ni
|
||||
@@ -60,8 +65,10 @@ has been important. :-) In alphabetical order:
|
||||
- Diego Elio Pettenò
|
||||
- Elbert Pol
|
||||
- Mikko Pouru
|
||||
- Pavel Raiskup
|
||||
- Robert Readman
|
||||
- Bernhard Reutner-Fischer
|
||||
- Eric S. Raymond
|
||||
- Cristian Rodríguez
|
||||
- Christian von Roques
|
||||
- Jukka Salmi
|
||||
@@ -72,6 +79,7 @@ has been important. :-) In alphabetical order:
|
||||
- Stuart Shelton
|
||||
- Jonathan Stott
|
||||
- Dan Stromberg
|
||||
- Vincent Torri
|
||||
- Paul Townsend
|
||||
- Mohammed Adnène Trojette
|
||||
- Alexey Tourbin
|
||||
|
||||
4
TODO
4
TODO
@@ -12,10 +12,6 @@ Known bugs
|
||||
it would be possible by switching from BT2/BT3/BT4 match finder to
|
||||
HC3/HC4.
|
||||
|
||||
The code to detect number of CPU cores doesn't count hyperthreading
|
||||
as multiple cores. In context of xz, it probably should.
|
||||
Hyperthreading is good at least with p7zip.
|
||||
|
||||
XZ Utils compress some files significantly worse than LZMA Utils.
|
||||
This is due to faster compression presets used by XZ Utils, and
|
||||
can often be worked around by using "xz --extreme". With some files
|
||||
|
||||
124
configure.ac
124
configure.ac
@@ -260,7 +260,7 @@ else
|
||||
done
|
||||
AC_MSG_RESULT([$enable_checks])
|
||||
fi
|
||||
if test "x$enable_checks_crc32" = xno ; then
|
||||
if test "x$enable_check_crc32" = xno ; then
|
||||
AC_MSG_ERROR([For now, the CRC32 check must always be enabled.])
|
||||
fi
|
||||
|
||||
@@ -328,15 +328,48 @@ AM_CONDITIONAL(COND_SMALL, test "x$enable_small" = xyes)
|
||||
#############
|
||||
|
||||
AC_MSG_CHECKING([if threading support is wanted])
|
||||
AC_ARG_ENABLE([threads], AC_HELP_STRING([--disable-threads],
|
||||
[Disable threading support.
|
||||
This makes some things thread-unsafe.]),
|
||||
AC_ARG_ENABLE([threads], AC_HELP_STRING([--enable-threads=METHOD],
|
||||
[Supported METHODS are `yes', `no', `posix', `win95', and
|
||||
`vista'. The default is `yes'. Using `no' together with
|
||||
--enable-small makes liblzma thread unsafe.]),
|
||||
[], [enable_threads=yes])
|
||||
if test "x$enable_threads" != xyes && test "x$enable_threads" != xno; then
|
||||
AC_MSG_RESULT([])
|
||||
AC_MSG_ERROR([--enable-threads accepts only \`yes' or \`no'])
|
||||
|
||||
if test "x$enable_threads" = xyes; then
|
||||
case $host_os in
|
||||
mingw*)
|
||||
case $host_cpu in
|
||||
i?86) enable_threads=win95 ;;
|
||||
*) enable_threads=vista ;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
enable_threads=posix
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_MSG_RESULT([$enable_threads])
|
||||
|
||||
case $enable_threads in
|
||||
posix | win95 | vista)
|
||||
AC_MSG_RESULT([yes, $enable_threads])
|
||||
;;
|
||||
no)
|
||||
AC_MSG_RESULT([no])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([])
|
||||
AC_MSG_ERROR([--enable-threads only accepts
|
||||
\`yes', \`no', \`posix', \`win95', or \`vista'])
|
||||
;;
|
||||
esac
|
||||
|
||||
# The Win95 threading lacks thread-safe one-time initialization function.
|
||||
# It's better to disallow it instead of allowing threaded but thread-unsafe
|
||||
# build.
|
||||
if test "x$enable_small$enable_threads" = xyeswin95; then
|
||||
AC_MSG_ERROR([--enable-threads=win95 and --enable-small cannot be
|
||||
used at the same time])
|
||||
fi
|
||||
|
||||
# We use the actual result a little later.
|
||||
|
||||
|
||||
@@ -443,7 +476,7 @@ fi
|
||||
echo
|
||||
echo "Initializing Automake:"
|
||||
|
||||
AM_INIT_AUTOMAKE([1.10 foreign tar-v7 filename-length-max=99])
|
||||
AM_INIT_AUTOMAKE([1.12 foreign tar-v7 filename-length-max=99 serial-tests])
|
||||
AC_PROG_LN_S
|
||||
|
||||
AC_PROG_CC_C99
|
||||
@@ -455,27 +488,49 @@ AM_PROG_CC_C_O
|
||||
AM_PROG_AS
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
if test "x$enable_threads" = xyes; then
|
||||
echo
|
||||
echo "Threading support:"
|
||||
AX_PTHREAD
|
||||
LIBS="$LIBS $PTHREAD_LIBS"
|
||||
AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS"
|
||||
case $enable_threads in
|
||||
posix)
|
||||
echo
|
||||
echo "POSIX threading support:"
|
||||
AX_PTHREAD([:]) dnl We don't need the HAVE_PTHREAD macro.
|
||||
LIBS="$LIBS $PTHREAD_LIBS"
|
||||
AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS"
|
||||
|
||||
dnl NOTE: PTHREAD_CC is ignored. It would be useful on AIX, but
|
||||
dnl it's tricky to get it right together with AC_PROG_CC_C99.
|
||||
dnl Thus, this is handled by telling the user in INSTALL to set
|
||||
dnl the correct CC manually.
|
||||
dnl NOTE: PTHREAD_CC is ignored. It would be useful on AIX,
|
||||
dnl but it's tricky to get it right together with
|
||||
dnl AC_PROG_CC_C99. Thus, this is handled by telling the
|
||||
dnl user in INSTALL to set the correct CC manually.
|
||||
|
||||
# These are nice to have but not mandatory.
|
||||
OLD_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
AC_CHECK_FUNCS([clock_gettime pthread_condattr_setclock])
|
||||
AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
|
||||
CFLAGS=$OLD_CFLAGS
|
||||
fi
|
||||
AM_CONDITIONAL([COND_THREADS], [test "x$ax_pthread_ok" = xyes])
|
||||
AC_DEFINE([MYTHREAD_POSIX], [1],
|
||||
[Define to 1 when using POSIX threads (pthreads).])
|
||||
|
||||
# These are nice to have but not mandatory.
|
||||
#
|
||||
# FIXME: xz uses clock_gettime if it is available and can do
|
||||
# it even when threading is disabled. Moving this outside
|
||||
# of pthread detection may be undesirable because then
|
||||
# liblzma may get linked against librt even when librt isn't
|
||||
# needed by liblzma.
|
||||
OLD_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
AC_CHECK_FUNCS([clock_gettime pthread_condattr_setclock])
|
||||
AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
|
||||
CFLAGS=$OLD_CFLAGS
|
||||
;;
|
||||
win95)
|
||||
AC_DEFINE([MYTHREAD_WIN95], [1], [Define to 1 when using
|
||||
Windows 95 (and thus XP) compatible threads.
|
||||
This avoids use of features that were added in
|
||||
Windows Vista.])
|
||||
;;
|
||||
vista)
|
||||
AC_DEFINE([MYTHREAD_VISTA], [1], [Define to 1 when using
|
||||
Windows Vista compatible threads. This uses
|
||||
features that are not available on Windows XP.])
|
||||
;;
|
||||
esac
|
||||
AM_CONDITIONAL([COND_THREADS], [test "x$enable_threads" != xno])
|
||||
|
||||
echo
|
||||
echo "Initializing Libtool:"
|
||||
@@ -496,7 +551,7 @@ AM_CONDITIONAL([COND_SHARED], [test "x$enable_shared" != xno])
|
||||
|
||||
echo
|
||||
echo "Initializing gettext:"
|
||||
AM_GNU_GETTEXT_VERSION([0.16.1])
|
||||
AM_GNU_GETTEXT_VERSION([0.18])
|
||||
AM_GNU_GETTEXT([external])
|
||||
|
||||
###############################################################################
|
||||
@@ -534,7 +589,7 @@ AC_TYPE_UINTPTR_T
|
||||
AC_CHECK_SIZEOF([size_t])
|
||||
|
||||
# The command line tool can copy high resolution timestamps if such
|
||||
# information is availabe in struct stat. Otherwise one second accuracy
|
||||
# information is available in struct stat. Otherwise one second accuracy
|
||||
# is used.
|
||||
AC_CHECK_MEMBERS([
|
||||
struct stat.st_atim.tv_nsec,
|
||||
@@ -653,6 +708,7 @@ if test "$GCC" = yes ; then
|
||||
for NEW_FLAG in \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-Wvla \
|
||||
-Wformat=2 \
|
||||
-Winit-self \
|
||||
-Wmissing-include-dirs \
|
||||
@@ -717,7 +773,6 @@ AC_CONFIG_FILES([
|
||||
po/Makefile.in
|
||||
lib/Makefile
|
||||
src/Makefile
|
||||
src/liblzma/liblzma.pc
|
||||
src/liblzma/Makefile
|
||||
src/liblzma/api/Makefile
|
||||
src/xz/Makefile
|
||||
@@ -748,3 +803,10 @@ if test x$tuklib_cv_cpucores_method = xunknown; then
|
||||
echo "WARNING:"
|
||||
echo "No supported method to detect the number of CPU cores."
|
||||
fi
|
||||
|
||||
if test "x$enable_threads$enable_small" = xnoyes; then
|
||||
echo
|
||||
echo "NOTE:"
|
||||
echo "liblzma will be thread unsafe due the combination"
|
||||
echo "of --disable-threads --enable-small."
|
||||
fi
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
## You can do whatever you want with this file.
|
||||
##
|
||||
|
||||
EXTRA_DIST = \
|
||||
translation.bash
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
repeat \
|
||||
sync_flush \
|
||||
|
||||
@@ -3,7 +3,7 @@ Debug tools
|
||||
-----------
|
||||
|
||||
This directory contains a few tiny programs that may be helpful when
|
||||
debugging LZMA Utils.
|
||||
debugging XZ Utils.
|
||||
|
||||
These tools are not meant to be installed. Often one needs to edit
|
||||
the source code a little to make the programs do the wanted things.
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
# This information is used by tuklib_cpucores.c.
|
||||
#
|
||||
# Supported methods:
|
||||
# - GetSystemInfo(): Windows (including Cygwin)
|
||||
# - sysctl(): BSDs, OS/2
|
||||
# - sysconf(): GNU/Linux, Solaris, Tru64, IRIX, AIX, Cygwin
|
||||
# - sysconf(): GNU/Linux, Solaris, Tru64, IRIX, AIX, Cygwin (but
|
||||
# GetSystemInfo() is used on Cygwin)
|
||||
# - pstat_getdynamic(): HP-UX
|
||||
#
|
||||
# COPYING
|
||||
@@ -30,6 +32,19 @@ AC_CHECK_HEADERS([sys/param.h])
|
||||
AC_CACHE_CHECK([how to detect the number of available CPU cores],
|
||||
[tuklib_cv_cpucores_method], [
|
||||
|
||||
# Maybe checking $host_os would be enough but this matches what
|
||||
# tuklib_cpucores.c does.
|
||||
#
|
||||
# NOTE: IRIX has a compiler that doesn't error out with #error, so use
|
||||
# a non-compilable text instead of #error to generate an error.
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
int main(void) { return 0; }
|
||||
#else
|
||||
compile error
|
||||
#endif
|
||||
]])], [tuklib_cv_cpucores_method=special], [
|
||||
|
||||
# Look for sysctl() solution first, because on OS/2, both sysconf()
|
||||
# and sysctl() pass the tests in this file, but only sysctl()
|
||||
# actually works.
|
||||
@@ -82,7 +97,7 @@ main(void)
|
||||
]])], [tuklib_cv_cpucores_method=pstat_getdynamic], [
|
||||
|
||||
tuklib_cv_cpucores_method=unknown
|
||||
])])])])
|
||||
])])])])])
|
||||
|
||||
case $tuklib_cv_cpucores_method in
|
||||
sysctl)
|
||||
|
||||
@@ -13,14 +13,26 @@ mkdir -p Resources
|
||||
# Abort immediately if something goes wrong.
|
||||
set -e
|
||||
|
||||
GCC="gcc-4.2"
|
||||
SDK="/Developer/SDKs/MacOSX10.5.sdk"
|
||||
MDT="10.5"
|
||||
GTT=i686-apple-darwin9
|
||||
|
||||
ARCHES1="-arch ppc -arch ppc64 -arch i386 -arch x86_64"
|
||||
ARCHES2="-arch ppc -arch i386"
|
||||
PKGFORMAT="10.5" # xar
|
||||
|
||||
# avoid "unknown required load command: 0x80000022" from linking on Snow Leopard
|
||||
uname -r | grep ^1 >/dev/null && LDFLAGS="$LDFLAGS -Wl,-no_compact_linkedit"
|
||||
|
||||
# Clean up if it was already configured.
|
||||
[ -f Makefile ] && make distclean
|
||||
|
||||
# Build the regular fat program
|
||||
|
||||
CC="gcc-4.0" \
|
||||
CFLAGS="-O2 -g -arch ppc -arch ppc64 -arch i386 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" \
|
||||
../configure --disable-dependency-tracking --disable-xzdec --disable-lzmadec i686-apple-darwin8
|
||||
CC="$GCC" \
|
||||
CFLAGS="-O2 -g $ARCHES1 -isysroot $SDK -mmacosx-version-min=$MDT" \
|
||||
../configure --disable-dependency-tracking --disable-xzdec --disable-lzmadec $GTT
|
||||
|
||||
make
|
||||
|
||||
@@ -32,9 +44,9 @@ make distclean
|
||||
|
||||
# Build the size-optimized program
|
||||
|
||||
CC="gcc-4.0" \
|
||||
CFLAGS="-Os -g -arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" \
|
||||
../configure --disable-dependency-tracking --disable-shared --disable-nls --disable-encoders --enable-small --disable-threads i686-apple-darwin8
|
||||
CC="$GCC" \
|
||||
CFLAGS="-Os -g $ARCHES2 -isysroot $SDK -mmacosx-version-min=$MDT" \
|
||||
../configure --disable-dependency-tracking --disable-shared --disable-nls --disable-encoders --enable-small --disable-threads $GTT
|
||||
|
||||
make -C src/liblzma
|
||||
make -C src/xzdec
|
||||
@@ -44,6 +56,19 @@ cp -a ../extra Root/usr/local/share/doc/xz
|
||||
|
||||
make distclean
|
||||
|
||||
# Move development files to different package
|
||||
|
||||
test -d liblzma && rm -r liblzma
|
||||
mkdir -p liblzma/usr/local
|
||||
|
||||
mv Root/usr/local/include liblzma/usr/local
|
||||
mv Root/usr/local/lib liblzma/usr/local
|
||||
|
||||
mkdir -p Root/usr/local/lib
|
||||
cp -p liblzma/usr/local/lib/liblzma.5.dylib Root/usr/local/lib
|
||||
mkdir -p liblzma/usr/local/share/doc/xz
|
||||
mv Root/usr/local/share/doc/xz/examples* liblzma/usr/local/share/doc/xz
|
||||
|
||||
# Strip debugging symbols and make relocatable
|
||||
|
||||
for bin in xz lzmainfo xzdec lzmadec; do
|
||||
@@ -56,19 +81,12 @@ for lib in liblzma.5.dylib; do
|
||||
install_name_tool -id @executable_path/../lib/liblzma.5.dylib Root/usr/local/lib/$lib
|
||||
done
|
||||
|
||||
strip -S Root/usr/local/lib/liblzma.a
|
||||
rm -f Root/usr/local/lib/liblzma.la
|
||||
|
||||
# Include pkg-config while making relocatable
|
||||
|
||||
sed -e 's|prefix=/usr/local|prefix=${pcfiledir}/../..|' < Root/usr/local/lib/pkgconfig/liblzma.pc > Root/liblzma.pc
|
||||
mv Root/liblzma.pc Root/usr/local/lib/pkgconfig/liblzma.pc
|
||||
|
||||
# Create tarball, but without the HFS+ attrib
|
||||
|
||||
rmdir debug lib po src/liblzma/api src/liblzma src/lzmainfo src/scripts src/xz src/xzdec src tests
|
||||
|
||||
( cd Root/usr/local; COPY_EXTENDED_ATTRIBUTES_DISABLE=true COPYFILE_DISABLE=true tar cvjf ../../../XZ.tbz * )
|
||||
( cd liblzma; COPY_EXTENDED_ATTRIBUTES_DISABLE=true COPYFILE_DISABLE=true tar cvjf ../liblzma.tbz ./usr/local )
|
||||
|
||||
# Include documentation files for package
|
||||
|
||||
@@ -80,12 +98,15 @@ cp -p ../COPYING Resources/License.txt
|
||||
ID="org.tukaani.xz"
|
||||
VERSION=`cd ..; sh build-aux/version.sh`
|
||||
PACKAGEMAKER=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker
|
||||
$PACKAGEMAKER -r Root/usr/local -l /usr/local -e Resources -i $ID -n $VERSION -t XZ -o XZ.pkg -g 10.4 --verbose
|
||||
$PACKAGEMAKER -r Root/usr/local -l /usr/local -e Resources -i $ID -n $VERSION -t XZ -o XZ.pkg -g $PKGFORMAT --verbose
|
||||
$PACKAGEMAKER -r liblzma -w -k -i $ID.liblzma -n $VERSION -o liblzma.pkg -g $PKGFORMAT --verbose
|
||||
|
||||
# Put the package in a disk image
|
||||
|
||||
if [ "$PKGFORMAT" != "10.5" ]; then
|
||||
hdiutil create -fs HFS+ -format UDZO -quiet -srcfolder XZ.pkg -ov XZ.dmg
|
||||
hdiutil internet-enable -yes -quiet XZ.dmg
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Build completed successfully."
|
||||
|
||||
@@ -15,8 +15,84 @@
|
||||
|
||||
#include "sysdefs.h"
|
||||
|
||||
// If any type of threading is enabled, #define MYTHREAD_ENABLED.
|
||||
#if defined(MYTHREAD_POSIX) || defined(MYTHREAD_WIN95) \
|
||||
|| defined(MYTHREAD_VISTA)
|
||||
# define MYTHREAD_ENABLED 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
|
||||
#ifdef MYTHREAD_ENABLED
|
||||
|
||||
////////////////////////////////////////
|
||||
// Shared betewen all threading types //
|
||||
////////////////////////////////////////
|
||||
|
||||
// Locks a mutex for a duration of a block.
|
||||
//
|
||||
// Perform mythread_mutex_lock(&mutex) in the beginning of a block
|
||||
// and mythread_mutex_unlock(&mutex) at the end of the block. "break"
|
||||
// may be used to unlock the mutex and jump out of the block.
|
||||
// mythread_sync blocks may be nested.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// mythread_sync(mutex) {
|
||||
// foo();
|
||||
// if (some_error)
|
||||
// break; // Skips bar()
|
||||
// bar();
|
||||
// }
|
||||
//
|
||||
// At least GCC optimizes the loops completely away so it doesn't slow
|
||||
// things down at all compared to plain mythread_mutex_lock(&mutex)
|
||||
// and mythread_mutex_unlock(&mutex) calls.
|
||||
//
|
||||
#define mythread_sync(mutex) mythread_sync_helper1(mutex, __LINE__)
|
||||
#define mythread_sync_helper1(mutex, line) mythread_sync_helper2(mutex, line)
|
||||
#define mythread_sync_helper2(mutex, line) \
|
||||
for (unsigned int mythread_i_ ## line = 0; \
|
||||
mythread_i_ ## line \
|
||||
? (mythread_mutex_unlock(&(mutex)), 0) \
|
||||
: (mythread_mutex_lock(&(mutex)), 1); \
|
||||
mythread_i_ ## line = 1) \
|
||||
for (unsigned int mythread_j_ ## line = 0; \
|
||||
!mythread_j_ ## line; \
|
||||
mythread_j_ ## line = 1)
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(MYTHREAD_ENABLED)
|
||||
|
||||
//////////////////
|
||||
// No threading //
|
||||
//////////////////
|
||||
|
||||
// Calls the given function once. This isn't thread safe.
|
||||
#define mythread_once(func) \
|
||||
do { \
|
||||
static bool once_ = false; \
|
||||
if (!once_) { \
|
||||
func(); \
|
||||
once_ = true; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#if !(defined(_WIN32) && !defined(__CYGWIN__))
|
||||
// Use sigprocmask() to set the signal mask in single-threaded programs.
|
||||
static inline void
|
||||
mythread_sigmask(int how, const sigset_t *restrict set,
|
||||
sigset_t *restrict oset)
|
||||
{
|
||||
int ret = sigprocmask(how, set, oset);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#elif defined(MYTHREAD_POSIX)
|
||||
|
||||
////////////////////
|
||||
// Using pthreads //
|
||||
@@ -26,82 +102,117 @@
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define MYTHREAD_RET_TYPE void *
|
||||
#define MYTHREAD_RET_VALUE NULL
|
||||
|
||||
#ifdef __VMS
|
||||
// Do nothing on OpenVMS. It doesn't have pthread_sigmask().
|
||||
#define mythread_sigmask(how, set, oset) do { } while (0)
|
||||
#else
|
||||
/// \brief Set the process signal mask
|
||||
///
|
||||
/// If threads are disabled, sigprocmask() is used instead
|
||||
/// of pthread_sigmask().
|
||||
#define mythread_sigmask(how, set, oset) \
|
||||
pthread_sigmask(how, set, oset)
|
||||
#endif
|
||||
|
||||
/// \brief Call the given function once
|
||||
///
|
||||
/// If threads are disabled, a thread-unsafe version is used.
|
||||
#define mythread_once(func) \
|
||||
do { \
|
||||
static pthread_once_t once_ = PTHREAD_ONCE_INIT; \
|
||||
pthread_once(&once_, &func); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// \brief Lock a mutex for a duration of a block
|
||||
///
|
||||
/// Perform pthread_mutex_lock(&mutex) in the beginning of a block
|
||||
/// and pthread_mutex_unlock(&mutex) at the end of the block. "break"
|
||||
/// may be used to unlock the mutex and jump out of the block.
|
||||
/// mythread_sync blocks may be nested.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// mythread_sync(mutex) {
|
||||
/// foo();
|
||||
/// if (some_error)
|
||||
/// break; // Skips bar()
|
||||
/// bar();
|
||||
/// }
|
||||
///
|
||||
/// At least GCC optimizes the loops completely away so it doesn't slow
|
||||
/// things down at all compared to plain pthread_mutex_lock(&mutex)
|
||||
/// and pthread_mutex_unlock(&mutex) calls.
|
||||
///
|
||||
#define mythread_sync(mutex) mythread_sync_helper(mutex, __LINE__)
|
||||
#define mythread_sync_helper(mutex, line) \
|
||||
for (unsigned int mythread_i_ ## line = 0; \
|
||||
mythread_i_ ## line \
|
||||
? (pthread_mutex_unlock(&(mutex)), 0) \
|
||||
: (pthread_mutex_lock(&(mutex)), 1); \
|
||||
mythread_i_ ## line = 1) \
|
||||
for (unsigned int mythread_j_ ## line = 0; \
|
||||
!mythread_j_ ## line; \
|
||||
mythread_j_ ## line = 1)
|
||||
|
||||
typedef pthread_t mythread;
|
||||
typedef pthread_mutex_t mythread_mutex;
|
||||
|
||||
typedef struct {
|
||||
/// Condition variable
|
||||
pthread_cond_t cond;
|
||||
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
/// Clock ID (CLOCK_REALTIME or CLOCK_MONOTONIC) associated with
|
||||
/// the condition variable
|
||||
// Clock ID (CLOCK_REALTIME or CLOCK_MONOTONIC) associated with
|
||||
// the condition variable.
|
||||
clockid_t clk_id;
|
||||
#endif
|
||||
|
||||
} mythread_cond;
|
||||
|
||||
typedef struct timespec mythread_condtime;
|
||||
|
||||
/// \brief Initialize a condition variable to use CLOCK_MONOTONIC
|
||||
///
|
||||
/// Using CLOCK_MONOTONIC instead of the default CLOCK_REALTIME makes the
|
||||
/// timeout in pthread_cond_timedwait() work correctly also if system time
|
||||
/// is suddenly changed. Unfortunately CLOCK_MONOTONIC isn't available
|
||||
/// everywhere while the default CLOCK_REALTIME is, so the default is
|
||||
/// used if CLOCK_MONOTONIC isn't available.
|
||||
|
||||
// Calls the given function once in a thread-safe way.
|
||||
#define mythread_once(func) \
|
||||
do { \
|
||||
static pthread_once_t once_ = PTHREAD_ONCE_INIT; \
|
||||
pthread_once(&once_, &func); \
|
||||
} while (0)
|
||||
|
||||
|
||||
// Use pthread_sigmask() to set the signal mask in multi-threaded programs.
|
||||
// Do nothing on OpenVMS since it lacks pthread_sigmask().
|
||||
static inline void
|
||||
mythread_sigmask(int how, const sigset_t *restrict set,
|
||||
sigset_t *restrict oset)
|
||||
{
|
||||
#ifdef __VMS
|
||||
(void)how;
|
||||
(void)set;
|
||||
(void)oset;
|
||||
#else
|
||||
int ret = pthread_sigmask(how, set, oset);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Creates a new thread with all signals blocked. Returns zero on success
|
||||
// and non-zero on error.
|
||||
static inline int
|
||||
mythread_create(mythread *thread, void *(*func)(void *arg), void *arg)
|
||||
{
|
||||
sigset_t old;
|
||||
sigset_t all;
|
||||
sigfillset(&all);
|
||||
|
||||
mythread_sigmask(SIG_SETMASK, &all, &old);
|
||||
const int ret = pthread_create(thread, NULL, func, arg);
|
||||
mythread_sigmask(SIG_SETMASK, &old, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Joins a thread. Returns zero on success and non-zero on error.
|
||||
static inline int
|
||||
mythread_join(mythread thread)
|
||||
{
|
||||
return pthread_join(thread, NULL);
|
||||
}
|
||||
|
||||
|
||||
// Initiatlizes a mutex. Returns zero on success and non-zero on error.
|
||||
static inline int
|
||||
mythread_mutex_init(mythread_mutex *mutex)
|
||||
{
|
||||
return pthread_mutex_init(mutex, NULL);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_mutex_destroy(mythread_mutex *mutex)
|
||||
{
|
||||
int ret = pthread_mutex_destroy(mutex);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_mutex_lock(mythread_mutex *mutex)
|
||||
{
|
||||
int ret = pthread_mutex_lock(mutex);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_mutex_unlock(mythread_mutex *mutex)
|
||||
{
|
||||
int ret = pthread_mutex_unlock(mutex);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
|
||||
// Initializes a condition variable.
|
||||
//
|
||||
// Using CLOCK_MONOTONIC instead of the default CLOCK_REALTIME makes the
|
||||
// timeout in pthread_cond_timedwait() work correctly also if system time
|
||||
// is suddenly changed. Unfortunately CLOCK_MONOTONIC isn't available
|
||||
// everywhere while the default CLOCK_REALTIME is, so the default is
|
||||
// used if CLOCK_MONOTONIC isn't available.
|
||||
//
|
||||
// If clock_gettime() isn't available at all, gettimeofday() will be used.
|
||||
static inline int
|
||||
mythread_cond_init(mythread_cond *mycond)
|
||||
{
|
||||
@@ -130,6 +241,8 @@ mythread_cond_init(mythread_cond *mycond)
|
||||
}
|
||||
|
||||
// If anything above fails, fall back to the default CLOCK_REALTIME.
|
||||
// POSIX requires that all implementations of clock_gettime() must
|
||||
// support at least CLOCK_REALTIME.
|
||||
# endif
|
||||
|
||||
mycond->clk_id = CLOCK_REALTIME;
|
||||
@@ -138,89 +251,268 @@ mythread_cond_init(mythread_cond *mycond)
|
||||
return pthread_cond_init(&mycond->cond, NULL);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Convert relative time to absolute time for use with timed wait
|
||||
///
|
||||
/// The current time of the clock associated with the condition variable
|
||||
/// is added to the relative time in *ts.
|
||||
static inline void
|
||||
mythread_cond_abstime(const mythread_cond *mycond, struct timespec *ts)
|
||||
mythread_cond_destroy(mythread_cond *cond)
|
||||
{
|
||||
int ret = pthread_cond_destroy(&cond->cond);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_cond_signal(mythread_cond *cond)
|
||||
{
|
||||
int ret = pthread_cond_signal(&cond->cond);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex)
|
||||
{
|
||||
int ret = pthread_cond_wait(&cond->cond, mutex);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
}
|
||||
|
||||
// Waits on a condition or until a timeout expires. If the timeout expires,
|
||||
// non-zero is returned, otherwise zero is returned.
|
||||
static inline int
|
||||
mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex,
|
||||
const mythread_condtime *condtime)
|
||||
{
|
||||
int ret = pthread_cond_timedwait(&cond->cond, mutex, condtime);
|
||||
assert(ret == 0 || ret == ETIMEDOUT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Sets condtime to the absolute time that is timeout_ms milliseconds
|
||||
// in the future. The type of the clock to use is taken from cond.
|
||||
static inline void
|
||||
mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond,
|
||||
uint32_t timeout_ms)
|
||||
{
|
||||
condtime->tv_sec = timeout_ms / 1000;
|
||||
condtime->tv_nsec = (timeout_ms % 1000) * 1000000;
|
||||
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
struct timespec now;
|
||||
clock_gettime(mycond->clk_id, &now);
|
||||
int ret = clock_gettime(cond->clk_id, &now);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
|
||||
ts->tv_sec += now.tv_sec;
|
||||
ts->tv_nsec += now.tv_nsec;
|
||||
condtime->tv_sec += now.tv_sec;
|
||||
condtime->tv_nsec += now.tv_nsec;
|
||||
#else
|
||||
(void)mycond;
|
||||
(void)cond;
|
||||
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
ts->tv_sec += now.tv_sec;
|
||||
ts->tv_nsec += now.tv_usec * 1000L;
|
||||
condtime->tv_sec += now.tv_sec;
|
||||
condtime->tv_nsec += now.tv_usec * 1000L;
|
||||
#endif
|
||||
|
||||
// tv_nsec must stay in the range [0, 999_999_999].
|
||||
if (ts->tv_nsec >= 1000000000L) {
|
||||
ts->tv_nsec -= 1000000000L;
|
||||
++ts->tv_sec;
|
||||
if (condtime->tv_nsec >= 1000000000L) {
|
||||
condtime->tv_nsec -= 1000000000L;
|
||||
++condtime->tv_sec;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#define mythread_cond_wait(mycondptr, mutexptr) \
|
||||
pthread_cond_wait(&(mycondptr)->cond, mutexptr)
|
||||
#elif defined(MYTHREAD_WIN95) || defined(MYTHREAD_VISTA)
|
||||
|
||||
#define mythread_cond_timedwait(mycondptr, mutexptr, abstimeptr) \
|
||||
pthread_cond_timedwait(&(mycondptr)->cond, mutexptr, abstimeptr)
|
||||
/////////////////////
|
||||
// Windows threads //
|
||||
/////////////////////
|
||||
|
||||
#define mythread_cond_signal(mycondptr) \
|
||||
pthread_cond_signal(&(mycondptr)->cond)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifdef MYTHREAD_VISTA
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
#define mythread_cond_broadcast(mycondptr) \
|
||||
pthread_cond_broadcast(&(mycondptr)->cond)
|
||||
#define MYTHREAD_RET_TYPE unsigned int __stdcall
|
||||
#define MYTHREAD_RET_VALUE 0
|
||||
|
||||
#define mythread_cond_destroy(mycondptr) \
|
||||
pthread_cond_destroy(&(mycondptr)->cond)
|
||||
typedef HANDLE mythread;
|
||||
typedef CRITICAL_SECTION mythread_mutex;
|
||||
|
||||
#ifdef MYTHREAD_WIN95
|
||||
typedef HANDLE mythread_cond;
|
||||
#else
|
||||
typedef CONDITION_VARIABLE mythread_cond;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
// Tick count (milliseconds) in the beginning of the timeout.
|
||||
// NOTE: This is 32 bits so it wraps around after 49.7 days.
|
||||
// Multi-day timeouts may not work as expected.
|
||||
DWORD start;
|
||||
|
||||
// Length of the timeout in milliseconds. The timeout expires
|
||||
// when the current tick count minus "start" is equal or greater
|
||||
// than "timeout".
|
||||
DWORD timeout;
|
||||
} mythread_condtime;
|
||||
|
||||
|
||||
// mythread_once() is only available with Vista threads.
|
||||
#ifdef MYTHREAD_VISTA
|
||||
#define mythread_once(func) \
|
||||
do { \
|
||||
static INIT_ONCE once_ = INIT_ONCE_STATIC_INIT; \
|
||||
BOOL pending_; \
|
||||
if (!InitOnceBeginInitialize(&once_, 0, &pending_, NULL)) \
|
||||
abort(); \
|
||||
if (pending_) \
|
||||
func(); \
|
||||
if (!InitOnceComplete(&once, 0, NULL)) \
|
||||
abort(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
||||
// mythread_sigmask() isn't available on Windows. Even a dummy version would
|
||||
// make no sense because the other POSIX signal functions are missing anyway.
|
||||
|
||||
|
||||
/// \brief Create a thread with all signals blocked
|
||||
static inline int
|
||||
mythread_create(pthread_t *thread, void *(*func)(void *arg), void *arg)
|
||||
mythread_create(mythread *thread,
|
||||
unsigned int (__stdcall *func)(void *arg), void *arg)
|
||||
{
|
||||
sigset_t old;
|
||||
sigset_t all;
|
||||
sigfillset(&all);
|
||||
uintptr_t ret = _beginthreadex(NULL, 0, func, arg, 0, NULL);
|
||||
if (ret == 0)
|
||||
return -1;
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &all, &old);
|
||||
const int ret = pthread_create(thread, NULL, func, arg);
|
||||
pthread_sigmask(SIG_SETMASK, &old, NULL);
|
||||
*thread = (HANDLE)ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
mythread_join(mythread thread)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0)
|
||||
ret = -1;
|
||||
|
||||
if (!CloseHandle(thread))
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
mythread_mutex_init(mythread_mutex *mutex)
|
||||
{
|
||||
InitializeCriticalSection(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_mutex_destroy(mythread_mutex *mutex)
|
||||
{
|
||||
DeleteCriticalSection(mutex);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_mutex_lock(mythread_mutex *mutex)
|
||||
{
|
||||
EnterCriticalSection(mutex);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_mutex_unlock(mythread_mutex *mutex)
|
||||
{
|
||||
LeaveCriticalSection(mutex);
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
mythread_cond_init(mythread_cond *cond)
|
||||
{
|
||||
#ifdef MYTHREAD_WIN95
|
||||
*cond = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
return *cond == NULL ? -1 : 0;
|
||||
#else
|
||||
InitializeConditionVariable(cond);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// No threading //
|
||||
//////////////////
|
||||
static inline void
|
||||
mythread_cond_destroy(mythread_cond *cond)
|
||||
{
|
||||
#ifdef MYTHREAD_WIN95
|
||||
CloseHandle(*cond);
|
||||
#else
|
||||
(void)cond;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define mythread_sigmask(how, set, oset) \
|
||||
sigprocmask(how, set, oset)
|
||||
static inline void
|
||||
mythread_cond_signal(mythread_cond *cond)
|
||||
{
|
||||
#ifdef MYTHREAD_WIN95
|
||||
SetEvent(*cond);
|
||||
#else
|
||||
WakeConditionVariable(cond);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex)
|
||||
{
|
||||
#ifdef MYTHREAD_WIN95
|
||||
LeaveCriticalSection(mutex);
|
||||
WaitForSingleObject(*cond, INFINITE);
|
||||
EnterCriticalSection(mutex);
|
||||
#else
|
||||
BOOL ret = SleepConditionVariableCS(cond, mutex, INFINITE);
|
||||
assert(ret);
|
||||
(void)ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define mythread_once(func) \
|
||||
do { \
|
||||
static bool once_ = false; \
|
||||
if (!once_) { \
|
||||
func(); \
|
||||
once_ = true; \
|
||||
} \
|
||||
} while (0)
|
||||
static inline int
|
||||
mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex,
|
||||
const mythread_condtime *condtime)
|
||||
{
|
||||
#ifdef MYTHREAD_WIN95
|
||||
LeaveCriticalSection(mutex);
|
||||
#endif
|
||||
|
||||
DWORD elapsed = GetTickCount() - condtime->start;
|
||||
DWORD timeout = elapsed >= condtime->timeout
|
||||
? 0 : condtime->timeout - elapsed;
|
||||
|
||||
#ifdef MYTHREAD_WIN95
|
||||
DWORD ret = WaitForSingleObject(*cond, timeout);
|
||||
assert(ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT);
|
||||
|
||||
EnterCriticalSection(mutex);
|
||||
|
||||
return ret == WAIT_TIMEOUT;
|
||||
#else
|
||||
BOOL ret = SleepConditionVariableCS(cond, mutex, timeout);
|
||||
assert(ret || GetLastError() == ERROR_TIMEOUT);
|
||||
return !ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond,
|
||||
uint32_t timeout)
|
||||
{
|
||||
(void)cond;
|
||||
condtime->start = GetTickCount();
|
||||
condtime->timeout = timeout;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
|
||||
#include "tuklib_cpucores.h"
|
||||
|
||||
#if defined(TUKLIB_CPUCORES_SYSCTL)
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0500
|
||||
# endif
|
||||
# include <windows.h>
|
||||
|
||||
#elif defined(TUKLIB_CPUCORES_SYSCTL)
|
||||
# ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
@@ -33,7 +39,12 @@ tuklib_cpucores(void)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
#if defined(TUKLIB_CPUCORES_SYSCTL)
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
ret = sysinfo.dwNumberOfProcessors;
|
||||
|
||||
#elif defined(TUKLIB_CPUCORES_SYSCTL)
|
||||
int name[2] = { CTL_HW, HW_NCPU };
|
||||
int cpus;
|
||||
size_t cpus_size = sizeof(cpus);
|
||||
|
||||
@@ -26,8 +26,8 @@ liblzma_la_CPPFLAGS = \
|
||||
-DTUKLIB_SYMBOL_PREFIX=lzma_
|
||||
liblzma_la_LDFLAGS = -no-undefined -version-info 5:99:0
|
||||
|
||||
EXTRA_DIST += liblzma.map validate_map.sh
|
||||
if COND_SYMVERS
|
||||
EXTRA_DIST += liblzma.map
|
||||
liblzma_la_LDFLAGS += \
|
||||
-Wl,--version-script=$(top_srcdir)/src/liblzma/liblzma.map
|
||||
endif
|
||||
@@ -94,3 +94,23 @@ endif
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = liblzma.pc
|
||||
EXTRA_DIST += liblzma.pc.in
|
||||
|
||||
pc_verbose = $(pc_verbose_@AM_V@)
|
||||
pc_verbose_ = $(pc_verbose_@AM_DEFAULT_V@)
|
||||
pc_verbose_0 = @echo " PC " $@;
|
||||
|
||||
liblzma.pc: $(srcdir)/liblzma.pc.in
|
||||
$(AM_V_at)rm -f $@
|
||||
$(pc_verbose)sed \
|
||||
-e 's,@prefix[@],$(prefix),g' \
|
||||
-e 's,@exec_prefix[@],$(exec_prefix),g' \
|
||||
-e 's,@libdir[@],$(libdir),g' \
|
||||
-e 's,@includedir[@],$(includedir),g' \
|
||||
-e 's,@PACKAGE_URL[@],$(PACKAGE_URL),g' \
|
||||
-e 's,@PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
|
||||
-e 's,@PTHREAD_CFLAGS[@],$(PTHREAD_CFLAGS),g' \
|
||||
-e 's,@LIBS[@],$(LIBS),g' \
|
||||
< $< > $@ || { rm -f $@; exit 1; }
|
||||
|
||||
clean-local:
|
||||
rm -f liblzma.pc
|
||||
|
||||
@@ -240,12 +240,12 @@ typedef enum {
|
||||
/**
|
||||
* \brief The `action' argument for lzma_code()
|
||||
*
|
||||
* After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or LZMA_FINISH,
|
||||
* the same `action' must is used until lzma_code() returns LZMA_STREAM_END.
|
||||
* Also, the amount of input (that is, strm->avail_in) must not be modified
|
||||
* by the application until lzma_code() returns LZMA_STREAM_END. Changing the
|
||||
* `action' or modifying the amount of input will make lzma_code() return
|
||||
* LZMA_PROG_ERROR.
|
||||
* After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, LZMA_FULL_BARRIER,
|
||||
* or LZMA_FINISH, the same `action' must is used until lzma_code() returns
|
||||
* LZMA_STREAM_END. Also, the amount of input (that is, strm->avail_in) must
|
||||
* not be modified by the application until lzma_code() returns
|
||||
* LZMA_STREAM_END. Changing the `action' or modifying the amount of input
|
||||
* will make lzma_code() return LZMA_PROG_ERROR.
|
||||
*/
|
||||
typedef enum {
|
||||
LZMA_RUN = 0,
|
||||
@@ -293,7 +293,7 @@ typedef enum {
|
||||
*
|
||||
* All the input data going to the current Block must have
|
||||
* been given to the encoder (the last bytes can still be
|
||||
* pending in* next_in). Call lzma_code() with LZMA_FULL_FLUSH
|
||||
* pending in *next_in). Call lzma_code() with LZMA_FULL_FLUSH
|
||||
* until it returns LZMA_STREAM_END. Then continue normally
|
||||
* with LZMA_RUN or finish the Stream with LZMA_FINISH.
|
||||
*
|
||||
@@ -302,6 +302,29 @@ typedef enum {
|
||||
* no unfinished Block, no empty Block is created.
|
||||
*/
|
||||
|
||||
LZMA_FULL_BARRIER = 4,
|
||||
/**<
|
||||
* \brief Finish encoding of the current Block
|
||||
*
|
||||
* This is like LZMA_FULL_FLUSH except that this doesn't
|
||||
* necessarily wait until all the input has been made
|
||||
* available via the output buffer. That is, lzma_code()
|
||||
* might return LZMA_STREAM_END as soon as all the input
|
||||
* has been consumed (avail_in == 0).
|
||||
*
|
||||
* LZMA_FULL_BARRIER is useful with a threaded encoder if
|
||||
* one wants to split the .xz Stream into Blocks at specific
|
||||
* offsets but doesn't care if the output isn't flushed
|
||||
* immediately. Using LZMA_FULL_BARRIER allows keeping
|
||||
* the threads busy while LZMA_FULL_FLUSH would make
|
||||
* lzma_code() wait until all the threads have finished
|
||||
* until more data could be passed to the encoder.
|
||||
*
|
||||
* With a lzma_stream initialized with the single-threaded
|
||||
* lzma_stream_encoder() or lzma_easy_encoder(),
|
||||
* LZMA_FULL_BARRIER is an alias for LZMA_FULL_FLUSH.
|
||||
*/
|
||||
|
||||
LZMA_FINISH = 3
|
||||
/**<
|
||||
* \brief Finish the coding operation
|
||||
@@ -456,7 +479,8 @@ typedef struct lzma_internal_s lzma_internal;
|
||||
*
|
||||
* Application may modify the values of total_in and total_out as it wants.
|
||||
* They are updated by liblzma to match the amount of data read and
|
||||
* written, but aren't used for anything else.
|
||||
* written but aren't used for anything else except as a possible return
|
||||
* values from lzma_get_progress().
|
||||
*/
|
||||
typedef struct {
|
||||
const uint8_t *next_in; /**< Pointer to the next input byte. */
|
||||
@@ -472,8 +496,10 @@ typedef struct {
|
||||
*
|
||||
* In most cases this is NULL which makes liblzma use
|
||||
* the standard malloc() and free().
|
||||
*
|
||||
* \note In 5.0.x this is not a const pointer.
|
||||
*/
|
||||
lzma_allocator *allocator;
|
||||
const lzma_allocator *allocator;
|
||||
|
||||
/** Internal state is not visible to applications. */
|
||||
lzma_internal *internal;
|
||||
@@ -554,6 +580,25 @@ extern LZMA_API(lzma_ret) lzma_code(lzma_stream *strm, lzma_action action)
|
||||
extern LZMA_API(void) lzma_end(lzma_stream *strm) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get progress information
|
||||
*
|
||||
* In single-threaded mode, applications can get progress information from
|
||||
* strm->total_in and strm->total_out. In multi-threaded mode this is less
|
||||
* useful because a significant amount of both input and output data gets
|
||||
* buffered internally by liblzma. This makes total_in and total_out give
|
||||
* misleading information and also makes the progress indicator updates
|
||||
* non-smooth.
|
||||
*
|
||||
* This function gives realistic progress information also in multi-threaded
|
||||
* mode by taking into account the progress made by each thread. In
|
||||
* single-threaded mode *progress_in and *progress_out are set to
|
||||
* strm->total_in and strm->total_out, respectively.
|
||||
*/
|
||||
extern LZMA_API(void) lzma_get_progress(lzma_stream *strm,
|
||||
uint64_t *progress_in, uint64_t *progress_out) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the memory usage of decoder filter chain
|
||||
*
|
||||
|
||||
@@ -341,7 +341,7 @@ extern LZMA_API(lzma_ret) lzma_block_header_encode(
|
||||
* block->header_size is invalid or block->filters is NULL.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_block_header_decode(lzma_block *block,
|
||||
lzma_allocator *allocator, const uint8_t *in)
|
||||
const lzma_allocator *allocator, const uint8_t *in)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
@@ -490,7 +490,25 @@ extern LZMA_API(size_t) lzma_block_buffer_bound(size_t uncompressed_size)
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_block_buffer_encode(
|
||||
lzma_block *block, lzma_allocator *allocator,
|
||||
lzma_block *block, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Single-call uncompress .xz Block encoder
|
||||
*
|
||||
* This is like lzma_block_buffer_encode() except this doesn't try to
|
||||
* compress the data and instead encodes the data using LZMA2 uncompressed
|
||||
* chunks. The required output buffer size can be determined with
|
||||
* lzma_block_buffer_bound().
|
||||
*
|
||||
* Since the data won't be compressed, this function ignores block->filters.
|
||||
* This function doesn't take lzma_allocator because this function doesn't
|
||||
* allocate any memory from the heap.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_block_uncomp_encode(lzma_block *block,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
@@ -524,7 +542,7 @@ extern LZMA_API(lzma_ret) lzma_block_buffer_encode(
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_block_buffer_decode(
|
||||
lzma_block *block, lzma_allocator *allocator,
|
||||
lzma_block *block, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
lzma_nothrow;
|
||||
|
||||
@@ -288,7 +288,8 @@ extern LZMA_API(lzma_ret) lzma_easy_encoder(
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_easy_buffer_encode(
|
||||
uint32_t preset, lzma_check check,
|
||||
lzma_allocator *allocator, const uint8_t *in, size_t in_size,
|
||||
const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
|
||||
|
||||
|
||||
@@ -436,7 +437,8 @@ extern LZMA_API(size_t) lzma_stream_buffer_bound(size_t uncompressed_size)
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_stream_buffer_encode(
|
||||
lzma_filter *filters, lzma_check check,
|
||||
lzma_allocator *allocator, const uint8_t *in, size_t in_size,
|
||||
const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
@@ -585,7 +587,8 @@ extern LZMA_API(lzma_ret) lzma_alone_decoder(
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_stream_buffer_decode(
|
||||
uint64_t *memlimit, uint32_t flags, lzma_allocator *allocator,
|
||||
uint64_t *memlimit, uint32_t flags,
|
||||
const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
@@ -116,8 +116,9 @@ extern LZMA_API(lzma_bool) lzma_filter_decoder_is_supported(lzma_vli id)
|
||||
* is not NULL.
|
||||
* - LZMA_PROG_ERROR: src or dest is NULL.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_filters_copy(const lzma_filter *src,
|
||||
lzma_filter *dest, lzma_allocator *allocator) lzma_nothrow;
|
||||
extern LZMA_API(lzma_ret) lzma_filters_copy(
|
||||
const lzma_filter *src, lzma_filter *dest,
|
||||
const lzma_allocator *allocator) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
@@ -256,7 +257,7 @@ extern LZMA_API(lzma_ret) lzma_filters_update(
|
||||
* won't necessarily meet that bound.)
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_raw_buffer_encode(
|
||||
const lzma_filter *filters, lzma_allocator *allocator,
|
||||
const lzma_filter *filters, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size, uint8_t *out,
|
||||
size_t *out_pos, size_t out_size) lzma_nothrow;
|
||||
|
||||
@@ -280,7 +281,7 @@ extern LZMA_API(lzma_ret) lzma_raw_buffer_encode(
|
||||
* which no data is written to is out[out_size].
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_raw_buffer_decode(
|
||||
const lzma_filter *filters, lzma_allocator *allocator,
|
||||
const lzma_filter *filters, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
|
||||
|
||||
@@ -356,7 +357,7 @@ extern LZMA_API(lzma_ret) lzma_properties_encode(
|
||||
* - LZMA_MEM_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_properties_decode(
|
||||
lzma_filter *filter, lzma_allocator *allocator,
|
||||
lzma_filter *filter, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size) lzma_nothrow;
|
||||
|
||||
|
||||
@@ -419,6 +420,6 @@ extern LZMA_API(lzma_ret) lzma_filter_flags_encode(const lzma_filter *filter,
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_filter_flags_decode(
|
||||
lzma_filter *filter, lzma_allocator *allocator,
|
||||
lzma_filter *filter, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
@@ -303,7 +303,7 @@ extern LZMA_API(uint64_t) lzma_index_memused(const lzma_index *i)
|
||||
* \return On success, a pointer to an empty initialized lzma_index is
|
||||
* returned. If allocation fails, NULL is returned.
|
||||
*/
|
||||
extern LZMA_API(lzma_index *) lzma_index_init(lzma_allocator *allocator)
|
||||
extern LZMA_API(lzma_index *) lzma_index_init(const lzma_allocator *allocator)
|
||||
lzma_nothrow;
|
||||
|
||||
|
||||
@@ -312,8 +312,8 @@ extern LZMA_API(lzma_index *) lzma_index_init(lzma_allocator *allocator)
|
||||
*
|
||||
* If i is NULL, this does nothing.
|
||||
*/
|
||||
extern LZMA_API(void) lzma_index_end(lzma_index *i, lzma_allocator *allocator)
|
||||
lzma_nothrow;
|
||||
extern LZMA_API(void) lzma_index_end(
|
||||
lzma_index *i, const lzma_allocator *allocator) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
@@ -341,7 +341,7 @@ extern LZMA_API(void) lzma_index_end(lzma_index *i, lzma_allocator *allocator)
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_index_append(
|
||||
lzma_index *i, lzma_allocator *allocator,
|
||||
lzma_index *i, const lzma_allocator *allocator,
|
||||
lzma_vli unpadded_size, lzma_vli uncompressed_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
@@ -564,8 +564,8 @@ extern LZMA_API(lzma_bool) lzma_index_iter_locate(
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_index_cat(
|
||||
lzma_index *dest, lzma_index *src, lzma_allocator *allocator)
|
||||
extern LZMA_API(lzma_ret) lzma_index_cat(lzma_index *dest, lzma_index *src,
|
||||
const lzma_allocator *allocator)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
@@ -575,7 +575,7 @@ extern LZMA_API(lzma_ret) lzma_index_cat(
|
||||
* \return A copy of the lzma_index, or NULL if memory allocation failed.
|
||||
*/
|
||||
extern LZMA_API(lzma_index *) lzma_index_dup(
|
||||
const lzma_index *i, lzma_allocator *allocator)
|
||||
const lzma_index *i, const lzma_allocator *allocator)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
@@ -677,6 +677,6 @@ extern LZMA_API(lzma_ret) lzma_index_buffer_encode(const lzma_index *i,
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,
|
||||
uint64_t *memlimit, lzma_allocator *allocator,
|
||||
uint64_t *memlimit, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size)
|
||||
lzma_nothrow;
|
||||
|
||||
@@ -37,7 +37,7 @@ typedef struct lzma_index_hash_s lzma_index_hash;
|
||||
* pointer than the index_hash that was given as an argument.
|
||||
*/
|
||||
extern LZMA_API(lzma_index_hash *) lzma_index_hash_init(
|
||||
lzma_index_hash *index_hash, lzma_allocator *allocator)
|
||||
lzma_index_hash *index_hash, const lzma_allocator *allocator)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ extern LZMA_API(lzma_index_hash *) lzma_index_hash_init(
|
||||
* \brief Deallocate lzma_index_hash structure
|
||||
*/
|
||||
extern LZMA_API(void) lzma_index_hash_end(
|
||||
lzma_index_hash *index_hash, lzma_allocator *allocator)
|
||||
lzma_index_hash *index_hash, const lzma_allocator *allocator)
|
||||
lzma_nothrow;
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
#define LZMA_VERSION_MAJOR 5
|
||||
#define LZMA_VERSION_MINOR 1
|
||||
#define LZMA_VERSION_PATCH 2
|
||||
#define LZMA_VERSION_PATCH 3
|
||||
#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_ALPHA
|
||||
|
||||
#ifndef LZMA_VERSION_COMMIT
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
/// \todo Crypto++ has x86 ASM optimizations. They use SSE so if they
|
||||
/// are imported to liblzma, SSE instructions need to be used
|
||||
/// conditionally to keep the code working on older boxes.
|
||||
/// We could also support using some external libary for SHA-256.
|
||||
//
|
||||
// This code is based on the code found from 7-Zip, which has a modified
|
||||
// version of the SHA-256 found from Crypto++ <http://www.cryptopp.com/>.
|
||||
|
||||
@@ -24,6 +24,7 @@ if COND_MAIN_ENCODER
|
||||
liblzma_la_SOURCES += \
|
||||
common/alone_encoder.c \
|
||||
common/block_buffer_encoder.c \
|
||||
common/block_buffer_encoder.h \
|
||||
common/block_encoder.c \
|
||||
common/block_encoder.h \
|
||||
common/block_header_encoder.c \
|
||||
|
||||
@@ -26,6 +26,11 @@ struct lzma_coder_s {
|
||||
SEQ_CODE,
|
||||
} sequence;
|
||||
|
||||
/// If true, reject files that are unlikely to be .lzma files.
|
||||
/// If false, more non-.lzma files get accepted and will give
|
||||
/// LZMA_DATA_ERROR either immediately or after a few output bytes.
|
||||
bool picky;
|
||||
|
||||
/// Position in the header fields
|
||||
size_t pos;
|
||||
|
||||
@@ -46,7 +51,7 @@ struct lzma_coder_s {
|
||||
|
||||
static lzma_ret
|
||||
alone_decode(lzma_coder *coder,
|
||||
lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size,
|
||||
@@ -68,13 +73,13 @@ alone_decode(lzma_coder *coder,
|
||||
|= (size_t)(in[*in_pos]) << (coder->pos * 8);
|
||||
|
||||
if (++coder->pos == 4) {
|
||||
if (coder->options.dict_size != UINT32_MAX) {
|
||||
if (coder->picky && coder->options.dict_size
|
||||
!= UINT32_MAX) {
|
||||
// A hack to ditch tons of false positives:
|
||||
// We allow only dictionary sizes that are
|
||||
// 2^n or 2^n + 2^(n-1). LZMA_Alone created
|
||||
// only files with 2^n, but accepts any
|
||||
// dictionary size. If someone complains, this
|
||||
// will be reconsidered.
|
||||
// dictionary size.
|
||||
uint32_t d = coder->options.dict_size - 1;
|
||||
d |= d >> 2;
|
||||
d |= d >> 3;
|
||||
@@ -103,9 +108,9 @@ alone_decode(lzma_coder *coder,
|
||||
|
||||
// Another hack to ditch false positives: Assume that
|
||||
// if the uncompressed size is known, it must be less
|
||||
// than 256 GiB. Again, if someone complains, this
|
||||
// will be reconsidered.
|
||||
if (coder->uncompressed_size != LZMA_VLI_UNKNOWN
|
||||
// than 256 GiB.
|
||||
if (coder->picky
|
||||
&& coder->uncompressed_size != LZMA_VLI_UNKNOWN
|
||||
&& coder->uncompressed_size
|
||||
>= (LZMA_VLI_C(1) << 38))
|
||||
return LZMA_FORMAT_ERROR;
|
||||
@@ -161,7 +166,7 @@ alone_decode(lzma_coder *coder,
|
||||
|
||||
|
||||
static void
|
||||
alone_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
alone_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
@@ -188,8 +193,8 @@ alone_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
uint64_t memlimit)
|
||||
lzma_alone_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
uint64_t memlimit, bool picky)
|
||||
{
|
||||
lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator);
|
||||
|
||||
@@ -208,6 +213,7 @@ lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
}
|
||||
|
||||
next->coder->sequence = SEQ_PROPERTIES;
|
||||
next->coder->picky = picky;
|
||||
next->coder->pos = 0;
|
||||
next->coder->options.dict_size = 0;
|
||||
next->coder->options.preset_dict = NULL;
|
||||
@@ -223,7 +229,7 @@ lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit)
|
||||
{
|
||||
lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit);
|
||||
lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit, false);
|
||||
|
||||
strm->internal->supported_actions[LZMA_RUN] = true;
|
||||
strm->internal->supported_actions[LZMA_FINISH] = true;
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
#include "common.h"
|
||||
|
||||
|
||||
extern lzma_ret lzma_alone_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, uint64_t memlimit);
|
||||
extern lzma_ret lzma_alone_decoder_init(
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
uint64_t memlimit, bool picky);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,7 +32,7 @@ struct lzma_coder_s {
|
||||
|
||||
static lzma_ret
|
||||
alone_encode(lzma_coder *coder,
|
||||
lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size,
|
||||
@@ -65,7 +65,7 @@ alone_encode(lzma_coder *coder,
|
||||
|
||||
|
||||
static void
|
||||
alone_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
alone_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
@@ -75,7 +75,7 @@ alone_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
// At least for now, this is not used by any internal function.
|
||||
static lzma_ret
|
||||
alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_options_lzma *options)
|
||||
{
|
||||
lzma_next_coder_init(&alone_encoder_init, next, allocator);
|
||||
@@ -137,7 +137,7 @@ alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
/*
|
||||
extern lzma_ret
|
||||
lzma_alone_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_options_alone *options)
|
||||
{
|
||||
lzma_next_coder_init(&alone_encoder_init, next, allocator, options);
|
||||
|
||||
@@ -30,7 +30,7 @@ struct lzma_coder_s {
|
||||
|
||||
|
||||
static lzma_ret
|
||||
auto_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
auto_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -54,7 +54,7 @@ auto_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
coder->memlimit, coder->flags));
|
||||
} else {
|
||||
return_if_error(lzma_alone_decoder_init(&coder->next,
|
||||
allocator, coder->memlimit));
|
||||
allocator, coder->memlimit, true));
|
||||
|
||||
// If the application wants to know about missing
|
||||
// integrity check or about the check in general, we
|
||||
@@ -100,7 +100,7 @@ auto_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static void
|
||||
auto_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
auto_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
@@ -143,7 +143,7 @@ auto_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
auto_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
auto_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
uint64_t memlimit, uint32_t flags)
|
||||
{
|
||||
lzma_next_coder_init(&auto_decoder_init, next, allocator);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_block_buffer_decode(lzma_block *block, lzma_allocator *allocator,
|
||||
lzma_block_buffer_decode(lzma_block *block, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "block_buffer_encoder.h"
|
||||
#include "block_encoder.h"
|
||||
#include "filter_encoder.h"
|
||||
#include "lzma2_encoder.h"
|
||||
@@ -28,8 +29,8 @@
|
||||
+ LZMA_CHECK_SIZE_MAX + 3) & ~3)
|
||||
|
||||
|
||||
static lzma_vli
|
||||
lzma2_bound(lzma_vli uncompressed_size)
|
||||
static uint64_t
|
||||
lzma2_bound(uint64_t uncompressed_size)
|
||||
{
|
||||
// Prevent integer overflow in overhead calculation.
|
||||
if (uncompressed_size > COMPRESSED_SIZE_MAX)
|
||||
@@ -39,7 +40,7 @@ lzma2_bound(lzma_vli uncompressed_size)
|
||||
// uncompressed_size up to the next multiple of LZMA2_CHUNK_MAX,
|
||||
// multiply by the size of per-chunk header, and add one byte for
|
||||
// the end marker.
|
||||
const lzma_vli overhead = ((uncompressed_size + LZMA2_CHUNK_MAX - 1)
|
||||
const uint64_t overhead = ((uncompressed_size + LZMA2_CHUNK_MAX - 1)
|
||||
/ LZMA2_CHUNK_MAX)
|
||||
* LZMA2_HEADER_UNCOMPRESSED + 1;
|
||||
|
||||
@@ -51,30 +52,36 @@ lzma2_bound(lzma_vli uncompressed_size)
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(size_t)
|
||||
lzma_block_buffer_bound(size_t uncompressed_size)
|
||||
extern uint64_t
|
||||
lzma_block_buffer_bound64(uint64_t uncompressed_size)
|
||||
{
|
||||
// For now, if the data doesn't compress, we always use uncompressed
|
||||
// chunks of LZMA2. In future we may use Subblock filter too, but
|
||||
// but for simplicity we probably will still use the same bound
|
||||
// calculation even though Subblock filter would have slightly less
|
||||
// overhead.
|
||||
lzma_vli lzma2_size = lzma2_bound(uncompressed_size);
|
||||
// If the data doesn't compress, we always use uncompressed
|
||||
// LZMA2 chunks.
|
||||
uint64_t lzma2_size = lzma2_bound(uncompressed_size);
|
||||
if (lzma2_size == 0)
|
||||
return 0;
|
||||
|
||||
// Take Block Padding into account.
|
||||
lzma2_size = (lzma2_size + 3) & ~LZMA_VLI_C(3);
|
||||
lzma2_size = (lzma2_size + 3) & ~UINT64_C(3);
|
||||
|
||||
#if SIZE_MAX < LZMA_VLI_MAX
|
||||
// Catch the possible integer overflow on 32-bit systems. There's no
|
||||
// overflow on 64-bit systems, because lzma2_bound() already takes
|
||||
// No risk of integer overflow because lzma2_bound() already takes
|
||||
// into account the size of the headers in the Block.
|
||||
if (SIZE_MAX - HEADERS_BOUND < lzma2_size)
|
||||
return HEADERS_BOUND + lzma2_size;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(size_t)
|
||||
lzma_block_buffer_bound(size_t uncompressed_size)
|
||||
{
|
||||
uint64_t ret = lzma_block_buffer_bound64(uncompressed_size);
|
||||
|
||||
#if SIZE_MAX < UINT64_MAX
|
||||
// Catch the possible integer overflow on 32-bit systems.
|
||||
if (ret > SIZE_MAX)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return HEADERS_BOUND + lzma2_size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,9 +89,6 @@ static lzma_ret
|
||||
block_encode_uncompressed(lzma_block *block, const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
// TODO: Figure out if the last filter is LZMA2 or Subblock and use
|
||||
// that filter to encode the uncompressed chunks.
|
||||
|
||||
// Use LZMA2 uncompressed chunks. We wouldn't need a dictionary at
|
||||
// all, but LZMA2 always requires a dictionary, so use the minimum
|
||||
// value to minimize memory usage of the decoder.
|
||||
@@ -160,16 +164,11 @@ block_encode_uncompressed(lzma_block *block, const uint8_t *in, size_t in_size,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
block_encode_normal(lzma_block *block, lzma_allocator *allocator,
|
||||
block_encode_normal(lzma_block *block, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
// Find out the size of the Block Header.
|
||||
block->compressed_size = lzma2_bound(in_size);
|
||||
if (block->compressed_size == 0)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
block->uncompressed_size = in_size;
|
||||
return_if_error(lzma_block_header_size(block));
|
||||
|
||||
// Reserve space for the Block Header and skip it for now.
|
||||
@@ -221,10 +220,11 @@ block_encode_normal(lzma_block *block, lzma_allocator *allocator,
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_block_buffer_encode(lzma_block *block, lzma_allocator *allocator,
|
||||
static lzma_ret
|
||||
block_buffer_encode(lzma_block *block, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
uint8_t *out, size_t *out_pos, size_t out_size,
|
||||
bool try_to_compress)
|
||||
{
|
||||
// Validate the arguments.
|
||||
if (block == NULL || (in == NULL && in_size != 0) || out == NULL
|
||||
@@ -237,7 +237,7 @@ lzma_block_buffer_encode(lzma_block *block, lzma_allocator *allocator,
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX
|
||||
|| block->filters == NULL)
|
||||
|| (try_to_compress && block->filters == NULL))
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
if (!lzma_check_is_supported(block->check))
|
||||
@@ -258,9 +258,19 @@ lzma_block_buffer_encode(lzma_block *block, lzma_allocator *allocator,
|
||||
|
||||
out_size -= check_size;
|
||||
|
||||
// Initialize block->uncompressed_size and calculate the worst-case
|
||||
// value for block->compressed_size.
|
||||
block->uncompressed_size = in_size;
|
||||
block->compressed_size = lzma2_bound(in_size);
|
||||
if (block->compressed_size == 0)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
// Do the actual compression.
|
||||
const lzma_ret ret = block_encode_normal(block, allocator,
|
||||
in, in_size, out, out_pos, out_size);
|
||||
lzma_ret ret = LZMA_BUF_ERROR;
|
||||
if (try_to_compress)
|
||||
ret = block_encode_normal(block, allocator,
|
||||
in, in_size, out, out_pos, out_size);
|
||||
|
||||
if (ret != LZMA_OK) {
|
||||
// If the error was something else than output buffer
|
||||
// becoming full, return the error now.
|
||||
@@ -303,3 +313,25 @@ lzma_block_buffer_encode(lzma_block *block, lzma_allocator *allocator,
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_block_buffer_encode(lzma_block *block, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
return block_buffer_encode(block, allocator,
|
||||
in, in_size, out, out_pos, out_size, true);
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_block_uncomp_encode(lzma_block *block,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
// It won't allocate any memory from heap so no need
|
||||
// for lzma_allocator.
|
||||
return block_buffer_encode(block, NULL,
|
||||
in, in_size, out, out_pos, out_size, false);
|
||||
}
|
||||
|
||||
24
src/liblzma/common/block_buffer_encoder.h
Normal file
24
src/liblzma/common/block_buffer_encoder.h
Normal file
@@ -0,0 +1,24 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file block_buffer_encoder.h
|
||||
/// \brief Single-call .xz Block encoder
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_BLOCK_BUFFER_ENCODER_H
|
||||
#define LZMA_BLOCK_BUFFER_ENCODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/// uint64_t version of lzma_block_buffer_bound(). It is used by
|
||||
/// stream_encoder_mt.c. Probably the original lzma_block_buffer_bound()
|
||||
/// should have been 64-bit, but fixing it would break the ABI.
|
||||
extern uint64_t lzma_block_buffer_bound64(uint64_t uncompressed_size);
|
||||
|
||||
#endif
|
||||
@@ -71,7 +71,7 @@ is_size_valid(lzma_vli size, lzma_vli reference)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
block_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
block_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -170,7 +170,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static void
|
||||
block_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
block_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
@@ -179,7 +179,7 @@ block_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
lzma_block *block)
|
||||
{
|
||||
lzma_next_coder_init(&lzma_block_decoder_init, next, allocator);
|
||||
|
||||
@@ -17,6 +17,6 @@
|
||||
|
||||
|
||||
extern lzma_ret lzma_block_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, lzma_block *block);
|
||||
const lzma_allocator *allocator, lzma_block *block);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,7 +45,7 @@ struct lzma_coder_s {
|
||||
|
||||
|
||||
static lzma_ret
|
||||
block_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
block_encode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -134,7 +134,7 @@ block_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static void
|
||||
block_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
block_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
@@ -143,7 +143,7 @@ block_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
block_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
block_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters lzma_attribute((__unused__)),
|
||||
const lzma_filter *reversed_filters)
|
||||
{
|
||||
@@ -156,7 +156,7 @@ block_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_block_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
lzma_block *block)
|
||||
{
|
||||
lzma_next_coder_init(&lzma_block_encoder_init, next, allocator);
|
||||
|
||||
@@ -42,6 +42,6 @@
|
||||
|
||||
|
||||
extern lzma_ret lzma_block_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, lzma_block *block);
|
||||
const lzma_allocator *allocator, lzma_block *block);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
static void
|
||||
free_properties(lzma_block *block, lzma_allocator *allocator)
|
||||
free_properties(lzma_block *block, const lzma_allocator *allocator)
|
||||
{
|
||||
// Free allocated filter options. The last array member is not
|
||||
// touched after the initialization in the beginning of
|
||||
@@ -32,7 +32,7 @@ free_properties(lzma_block *block, lzma_allocator *allocator)
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_block_header_decode(lzma_block *block,
|
||||
lzma_allocator *allocator, const uint8_t *in)
|
||||
const lzma_allocator *allocator, const uint8_t *in)
|
||||
{
|
||||
// NOTE: We consider the header to be corrupt not only when the
|
||||
// CRC32 doesn't match, but also when variable-length integers
|
||||
|
||||
@@ -36,7 +36,7 @@ lzma_version_string(void)
|
||||
///////////////////////
|
||||
|
||||
extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
|
||||
lzma_alloc(size_t size, lzma_allocator *allocator)
|
||||
lzma_alloc(size_t size, const lzma_allocator *allocator)
|
||||
{
|
||||
// Some malloc() variants return NULL if called with size == 0.
|
||||
if (size == 0)
|
||||
@@ -54,7 +54,7 @@ lzma_alloc(size_t size, lzma_allocator *allocator)
|
||||
|
||||
|
||||
extern void
|
||||
lzma_free(void *ptr, lzma_allocator *allocator)
|
||||
lzma_free(void *ptr, const lzma_allocator *allocator)
|
||||
{
|
||||
if (allocator != NULL && allocator->free != NULL)
|
||||
allocator->free(allocator->opaque, ptr);
|
||||
@@ -88,7 +88,7 @@ lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_next_filter_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
lzma_next_coder_init(filters[0].init, next, allocator);
|
||||
@@ -99,7 +99,7 @@ lzma_next_filter_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_next_filter_update(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_filter_update(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *reversed_filters)
|
||||
{
|
||||
// Check that the application isn't trying to change the Filter ID.
|
||||
@@ -117,7 +117,7 @@ lzma_next_filter_update(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern void
|
||||
lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator)
|
||||
lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
|
||||
{
|
||||
if (next->init != (uintptr_t)(NULL)) {
|
||||
// To avoid tiny end functions that simply call
|
||||
@@ -176,7 +176,7 @@ lzma_code(lzma_stream *strm, lzma_action action)
|
||||
|| (strm->next_out == NULL && strm->avail_out != 0)
|
||||
|| strm->internal == NULL
|
||||
|| strm->internal->next.code == NULL
|
||||
|| (unsigned int)(action) > LZMA_FINISH
|
||||
|| (unsigned int)(action) > LZMA_ACTION_MAX
|
||||
|| !strm->internal->supported_actions[action])
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
@@ -211,6 +211,10 @@ lzma_code(lzma_stream *strm, lzma_action action)
|
||||
case LZMA_FINISH:
|
||||
strm->internal->sequence = ISEQ_FINISH;
|
||||
break;
|
||||
|
||||
case LZMA_FULL_BARRIER:
|
||||
strm->internal->sequence = ISEQ_FULL_BARRIER;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -238,6 +242,13 @@ lzma_code(lzma_stream *strm, lzma_action action)
|
||||
|
||||
break;
|
||||
|
||||
case ISEQ_FULL_BARRIER:
|
||||
if (action != LZMA_FULL_BARRIER
|
||||
|| strm->internal->avail_in != strm->avail_in)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
break;
|
||||
|
||||
case ISEQ_END:
|
||||
return LZMA_STREAM_END;
|
||||
|
||||
@@ -288,7 +299,9 @@ lzma_code(lzma_stream *strm, lzma_action action)
|
||||
|
||||
case LZMA_STREAM_END:
|
||||
if (strm->internal->sequence == ISEQ_SYNC_FLUSH
|
||||
|| strm->internal->sequence == ISEQ_FULL_FLUSH)
|
||||
|| strm->internal->sequence == ISEQ_FULL_FLUSH
|
||||
|| strm->internal->sequence
|
||||
== ISEQ_FULL_BARRIER)
|
||||
strm->internal->sequence = ISEQ_RUN;
|
||||
else
|
||||
strm->internal->sequence = ISEQ_END;
|
||||
@@ -328,6 +341,22 @@ lzma_end(lzma_stream *strm)
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(void)
|
||||
lzma_get_progress(lzma_stream *strm,
|
||||
uint64_t *progress_in, uint64_t *progress_out)
|
||||
{
|
||||
if (strm->internal->next.get_progress != NULL) {
|
||||
strm->internal->next.get_progress(strm->internal->next.coder,
|
||||
progress_in, progress_out);
|
||||
} else {
|
||||
*progress_in = strm->total_in;
|
||||
*progress_out = strm->total_out;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_check)
|
||||
lzma_get_check(const lzma_stream *strm)
|
||||
{
|
||||
|
||||
@@ -78,6 +78,10 @@
|
||||
| LZMA_CONCATENATED )
|
||||
|
||||
|
||||
/// Largest valid lzma_action value as unsigned integer.
|
||||
#define LZMA_ACTION_MAX ((unsigned int)(LZMA_FULL_BARRIER))
|
||||
|
||||
|
||||
/// Special return value (lzma_ret) to indicate that a timeout was reached
|
||||
/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to
|
||||
/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because
|
||||
@@ -96,7 +100,7 @@ typedef struct lzma_filter_info_s lzma_filter_info;
|
||||
|
||||
/// Type of a function used to initialize a filter encoder or decoder
|
||||
typedef lzma_ret (*lzma_init_function)(
|
||||
lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
/// Type of a function to do some kind of coding work (filters, Stream,
|
||||
@@ -104,7 +108,7 @@ typedef lzma_ret (*lzma_init_function)(
|
||||
/// input and output buffers, but for simplicity they still use this same
|
||||
/// function prototype.
|
||||
typedef lzma_ret (*lzma_code_function)(
|
||||
lzma_coder *coder, lzma_allocator *allocator,
|
||||
lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size,
|
||||
@@ -112,7 +116,7 @@ typedef lzma_ret (*lzma_code_function)(
|
||||
|
||||
/// Type of a function to free the memory allocated for the coder
|
||||
typedef void (*lzma_end_function)(
|
||||
lzma_coder *coder, lzma_allocator *allocator);
|
||||
lzma_coder *coder, const lzma_allocator *allocator);
|
||||
|
||||
|
||||
/// Raw coder validates and converts an array of lzma_filter structures to
|
||||
@@ -155,6 +159,11 @@ struct lzma_next_coder_s {
|
||||
/// lzma_next_coder.coder.
|
||||
lzma_end_function end;
|
||||
|
||||
/// Pointer to a function to get progress information. If this is NULL,
|
||||
/// lzma_stream.total_in and .total_out are used instead.
|
||||
void (*get_progress)(lzma_coder *coder,
|
||||
uint64_t *progress_in, uint64_t *progress_out);
|
||||
|
||||
/// Pointer to function to return the type of the integrity check.
|
||||
/// Most coders won't support this.
|
||||
lzma_check (*get_check)(const lzma_coder *coder);
|
||||
@@ -166,7 +175,7 @@ struct lzma_next_coder_s {
|
||||
|
||||
/// Update the filter-specific options or the whole filter chain
|
||||
/// in the encoder.
|
||||
lzma_ret (*update)(lzma_coder *coder, lzma_allocator *allocator,
|
||||
lzma_ret (*update)(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters,
|
||||
const lzma_filter *reversed_filters);
|
||||
};
|
||||
@@ -180,6 +189,7 @@ struct lzma_next_coder_s {
|
||||
.id = LZMA_VLI_UNKNOWN, \
|
||||
.code = NULL, \
|
||||
.end = NULL, \
|
||||
.get_progress = NULL, \
|
||||
.get_check = NULL, \
|
||||
.memconfig = NULL, \
|
||||
.update = NULL, \
|
||||
@@ -201,6 +211,7 @@ struct lzma_internal_s {
|
||||
ISEQ_SYNC_FLUSH,
|
||||
ISEQ_FULL_FLUSH,
|
||||
ISEQ_FINISH,
|
||||
ISEQ_FULL_BARRIER,
|
||||
ISEQ_END,
|
||||
ISEQ_ERROR,
|
||||
} sequence;
|
||||
@@ -211,7 +222,7 @@ struct lzma_internal_s {
|
||||
size_t avail_in;
|
||||
|
||||
/// Indicates which lzma_action values are allowed by next.code.
|
||||
bool supported_actions[4];
|
||||
bool supported_actions[LZMA_ACTION_MAX + 1];
|
||||
|
||||
/// If true, lzma_code will return LZMA_BUF_ERROR if no progress was
|
||||
/// made (no input consumed and no output produced by next.code).
|
||||
@@ -220,11 +231,11 @@ struct lzma_internal_s {
|
||||
|
||||
|
||||
/// Allocates memory
|
||||
extern void *lzma_alloc(size_t size, lzma_allocator *allocator)
|
||||
extern void *lzma_alloc(size_t size, const lzma_allocator *allocator)
|
||||
lzma_attribute((__malloc__)) lzma_attr_alloc_size(1);
|
||||
|
||||
/// Frees memory
|
||||
extern void lzma_free(void *ptr, lzma_allocator *allocator);
|
||||
extern void lzma_free(void *ptr, const lzma_allocator *allocator);
|
||||
|
||||
|
||||
/// Allocates strm->internal if it is NULL, and initializes *strm and
|
||||
@@ -236,17 +247,19 @@ extern lzma_ret lzma_strm_init(lzma_stream *strm);
|
||||
/// than the filter being initialized now. This way the actual filter
|
||||
/// initialization functions don't need to use lzma_next_coder_init macro.
|
||||
extern lzma_ret lzma_next_filter_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
/// Update the next filter in the chain, if any. This checks that
|
||||
/// the application is not trying to change the Filter IDs.
|
||||
extern lzma_ret lzma_next_filter_update(
|
||||
lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *reversed_filters);
|
||||
|
||||
/// Frees the memory allocated for next->coder either using next->end or,
|
||||
/// if next->end is NULL, using lzma_free.
|
||||
extern void lzma_next_end(lzma_next_coder *next, lzma_allocator *allocator);
|
||||
extern void lzma_next_end(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator);
|
||||
|
||||
|
||||
/// Copy as much data as possible from in[] to out[] and update *in_pos
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_easy_buffer_encode(uint32_t preset, lzma_check check,
|
||||
lzma_allocator *allocator, const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
const lzma_allocator *allocator, const uint8_t *in,
|
||||
size_t in_size, uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
lzma_options_easy opt_easy;
|
||||
if (lzma_easy_preset(&opt_easy, preset))
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_raw_buffer_decode(const lzma_filter *filters, lzma_allocator *allocator,
|
||||
lzma_raw_buffer_decode(
|
||||
const lzma_filter *filters, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_raw_buffer_encode(const lzma_filter *filters, lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size, uint8_t *out,
|
||||
size_t *out_pos, size_t out_size)
|
||||
lzma_raw_buffer_encode(
|
||||
const lzma_filter *filters, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
// Validate what isn't validated later in filter_common.c.
|
||||
if ((in == NULL && in_size != 0) || out == NULL
|
||||
|
||||
@@ -123,7 +123,7 @@ static const struct {
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_filters_copy(const lzma_filter *src, lzma_filter *dest,
|
||||
lzma_allocator *allocator)
|
||||
const lzma_allocator *allocator)
|
||||
{
|
||||
if (src == NULL || dest == NULL)
|
||||
return LZMA_PROG_ERROR;
|
||||
@@ -239,7 +239,7 @@ validate_chain(const lzma_filter *filters, size_t *count)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_raw_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_raw_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *options,
|
||||
lzma_filter_find coder_find, bool is_encoder)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ typedef const lzma_filter_coder *(*lzma_filter_find)(lzma_vli id);
|
||||
|
||||
|
||||
extern lzma_ret lzma_raw_coder_init(
|
||||
lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters,
|
||||
lzma_filter_find coder_find, bool is_encoder);
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ typedef struct {
|
||||
/// \return - LZMA_OK: Properties decoded successfully.
|
||||
/// - LZMA_OPTIONS_ERROR: Unsupported properties
|
||||
/// - LZMA_MEM_ERROR: Memory allocation failed.
|
||||
lzma_ret (*props_decode)(void **options, lzma_allocator *allocator,
|
||||
lzma_ret (*props_decode)(
|
||||
void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size);
|
||||
|
||||
} lzma_filter_decoder;
|
||||
@@ -136,7 +137,7 @@ lzma_filter_decoder_is_supported(lzma_vli id)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_raw_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_raw_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *options)
|
||||
{
|
||||
return lzma_raw_coder_init(next, allocator,
|
||||
@@ -165,7 +166,7 @@ lzma_raw_decoder_memusage(const lzma_filter *filters)
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_properties_decode(lzma_filter *filter, lzma_allocator *allocator,
|
||||
lzma_properties_decode(lzma_filter *filter, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size)
|
||||
{
|
||||
// Make it always NULL so that the caller can always safely free() it.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
extern lzma_ret lzma_raw_decoder_init(
|
||||
lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *options);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -196,7 +196,7 @@ lzma_filters_update(lzma_stream *strm, const lzma_filter *filters)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_raw_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_raw_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *options)
|
||||
{
|
||||
return lzma_raw_coder_init(next, allocator,
|
||||
|
||||
@@ -21,7 +21,7 @@ extern uint64_t lzma_mt_block_size(const lzma_filter *filters);
|
||||
|
||||
|
||||
extern lzma_ret lzma_raw_encoder_init(
|
||||
lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_filter_flags_decode(
|
||||
lzma_filter *filter, lzma_allocator *allocator,
|
||||
lzma_filter *filter, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size)
|
||||
{
|
||||
// Set the pointer to NULL so the caller can always safely free it.
|
||||
|
||||
@@ -191,8 +191,8 @@ index_tree_init(index_tree *tree)
|
||||
|
||||
/// Helper for index_tree_end()
|
||||
static void
|
||||
index_tree_node_end(index_tree_node *node, lzma_allocator *allocator,
|
||||
void (*free_func)(void *node, lzma_allocator *allocator))
|
||||
index_tree_node_end(index_tree_node *node, const lzma_allocator *allocator,
|
||||
void (*free_func)(void *node, const lzma_allocator *allocator))
|
||||
{
|
||||
// The tree won't ever be very huge, so recursion should be fine.
|
||||
// 20 levels in the tree is likely quite a lot already in practice.
|
||||
@@ -215,8 +215,8 @@ index_tree_node_end(index_tree_node *node, lzma_allocator *allocator,
|
||||
/// to free the Record groups from each index_stream before freeing
|
||||
/// the index_stream itself.
|
||||
static void
|
||||
index_tree_end(index_tree *tree, lzma_allocator *allocator,
|
||||
void (*free_func)(void *node, lzma_allocator *allocator))
|
||||
index_tree_end(index_tree *tree, const lzma_allocator *allocator,
|
||||
void (*free_func)(void *node, const lzma_allocator *allocator))
|
||||
{
|
||||
if (tree->root != NULL)
|
||||
index_tree_node_end(tree->root, allocator, free_func);
|
||||
@@ -340,7 +340,7 @@ index_tree_locate(const index_tree *tree, lzma_vli target)
|
||||
static index_stream *
|
||||
index_stream_init(lzma_vli compressed_base, lzma_vli uncompressed_base,
|
||||
lzma_vli stream_number, lzma_vli block_number_base,
|
||||
lzma_allocator *allocator)
|
||||
const lzma_allocator *allocator)
|
||||
{
|
||||
index_stream *s = lzma_alloc(sizeof(index_stream), allocator);
|
||||
if (s == NULL)
|
||||
@@ -368,7 +368,7 @@ index_stream_init(lzma_vli compressed_base, lzma_vli uncompressed_base,
|
||||
|
||||
/// Free the memory allocated for a Stream and its Record groups.
|
||||
static void
|
||||
index_stream_end(void *node, lzma_allocator *allocator)
|
||||
index_stream_end(void *node, const lzma_allocator *allocator)
|
||||
{
|
||||
index_stream *s = node;
|
||||
index_tree_end(&s->groups, allocator, NULL);
|
||||
@@ -377,7 +377,7 @@ index_stream_end(void *node, lzma_allocator *allocator)
|
||||
|
||||
|
||||
static lzma_index *
|
||||
index_init_plain(lzma_allocator *allocator)
|
||||
index_init_plain(const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_index *i = lzma_alloc(sizeof(lzma_index), allocator);
|
||||
if (i != NULL) {
|
||||
@@ -395,7 +395,7 @@ index_init_plain(lzma_allocator *allocator)
|
||||
|
||||
|
||||
extern LZMA_API(lzma_index *)
|
||||
lzma_index_init(lzma_allocator *allocator)
|
||||
lzma_index_init(const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_index *i = index_init_plain(allocator);
|
||||
if (i == NULL)
|
||||
@@ -414,7 +414,7 @@ lzma_index_init(lzma_allocator *allocator)
|
||||
|
||||
|
||||
extern LZMA_API(void)
|
||||
lzma_index_end(lzma_index *i, lzma_allocator *allocator)
|
||||
lzma_index_end(lzma_index *i, const lzma_allocator *allocator)
|
||||
{
|
||||
// NOTE: If you modify this function, check also the bottom
|
||||
// of lzma_index_cat().
|
||||
@@ -637,7 +637,7 @@ lzma_index_stream_padding(lzma_index *i, lzma_vli stream_padding)
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_index_append(lzma_index *i, lzma_allocator *allocator,
|
||||
lzma_index_append(lzma_index *i, const lzma_allocator *allocator,
|
||||
lzma_vli unpadded_size, lzma_vli uncompressed_size)
|
||||
{
|
||||
// Validate.
|
||||
@@ -765,7 +765,7 @@ index_cat_helper(const index_cat_info *info, index_stream *this)
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_index_cat(lzma_index *restrict dest, lzma_index *restrict src,
|
||||
lzma_allocator *allocator)
|
||||
const lzma_allocator *allocator)
|
||||
{
|
||||
const lzma_vli dest_file_size = lzma_index_file_size(dest);
|
||||
|
||||
@@ -859,7 +859,7 @@ lzma_index_cat(lzma_index *restrict dest, lzma_index *restrict src,
|
||||
|
||||
/// Duplicate an index_stream.
|
||||
static index_stream *
|
||||
index_dup_stream(const index_stream *src, lzma_allocator *allocator)
|
||||
index_dup_stream(const index_stream *src, const lzma_allocator *allocator)
|
||||
{
|
||||
// Catch a somewhat theoretical integer overflow.
|
||||
if (src->record_count > PREALLOC_MAX)
|
||||
@@ -919,7 +919,7 @@ index_dup_stream(const index_stream *src, lzma_allocator *allocator)
|
||||
|
||||
|
||||
extern LZMA_API(lzma_index *)
|
||||
lzma_index_dup(const lzma_index *src, lzma_allocator *allocator)
|
||||
lzma_index_dup(const lzma_index *src, const lzma_allocator *allocator)
|
||||
{
|
||||
// Allocate the base structure (no initial Stream).
|
||||
lzma_index *dest = index_init_plain(allocator);
|
||||
|
||||
@@ -54,7 +54,7 @@ struct lzma_coder_s {
|
||||
|
||||
|
||||
static lzma_ret
|
||||
index_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
index_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size,
|
||||
uint8_t *restrict out lzma_attribute((__unused__)),
|
||||
@@ -207,7 +207,7 @@ out:
|
||||
|
||||
|
||||
static void
|
||||
index_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
index_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_index_end(coder->index, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
@@ -234,7 +234,7 @@ index_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
index_decoder_reset(lzma_coder *coder, lzma_allocator *allocator,
|
||||
index_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
lzma_index **i, uint64_t memlimit)
|
||||
{
|
||||
// Remember the pointer given by the application. We will set it
|
||||
@@ -261,7 +261,7 @@ index_decoder_reset(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
index_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
index_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
lzma_index **i, uint64_t memlimit)
|
||||
{
|
||||
lzma_next_coder_init(&index_decoder_init, next, allocator);
|
||||
@@ -299,8 +299,8 @@ lzma_index_decoder(lzma_stream *strm, lzma_index **i, uint64_t memlimit)
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_index_buffer_decode(
|
||||
lzma_index **i, uint64_t *memlimit, lzma_allocator *allocator,
|
||||
lzma_index_buffer_decode(lzma_index **i, uint64_t *memlimit,
|
||||
const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size)
|
||||
{
|
||||
// Sanity checks
|
||||
|
||||
@@ -42,7 +42,7 @@ struct lzma_coder_s {
|
||||
|
||||
static lzma_ret
|
||||
index_encode(lzma_coder *coder,
|
||||
lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const uint8_t *restrict in lzma_attribute((__unused__)),
|
||||
size_t *restrict in_pos lzma_attribute((__unused__)),
|
||||
size_t in_size lzma_attribute((__unused__)),
|
||||
@@ -159,7 +159,7 @@ out:
|
||||
|
||||
|
||||
static void
|
||||
index_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
index_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
@@ -181,7 +181,7 @@ index_encoder_reset(lzma_coder *coder, const lzma_index *i)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_index_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_index_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_index *i)
|
||||
{
|
||||
lzma_next_coder_init(&lzma_index_encoder_init, next, allocator);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
extern lzma_ret lzma_index_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_index *i);
|
||||
const lzma_allocator *allocator, const lzma_index *i);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,7 +70,8 @@ struct lzma_index_hash_s {
|
||||
|
||||
|
||||
extern LZMA_API(lzma_index_hash *)
|
||||
lzma_index_hash_init(lzma_index_hash *index_hash, lzma_allocator *allocator)
|
||||
lzma_index_hash_init(lzma_index_hash *index_hash,
|
||||
const lzma_allocator *allocator)
|
||||
{
|
||||
if (index_hash == NULL) {
|
||||
index_hash = lzma_alloc(sizeof(lzma_index_hash), allocator);
|
||||
@@ -101,7 +102,8 @@ lzma_index_hash_init(lzma_index_hash *index_hash, lzma_allocator *allocator)
|
||||
|
||||
|
||||
extern LZMA_API(void)
|
||||
lzma_index_hash_end(lzma_index_hash *index_hash, lzma_allocator *allocator)
|
||||
lzma_index_hash_end(lzma_index_hash *index_hash,
|
||||
const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_free(index_hash, allocator);
|
||||
return;
|
||||
|
||||
@@ -54,7 +54,7 @@ lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_outq_init(lzma_outq *outq, lzma_allocator *allocator,
|
||||
lzma_outq_init(lzma_outq *outq, const lzma_allocator *allocator,
|
||||
uint64_t buf_size_max, uint32_t threads)
|
||||
{
|
||||
uint64_t bufs_alloc_size;
|
||||
@@ -98,7 +98,7 @@ lzma_outq_init(lzma_outq *outq, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern void
|
||||
lzma_outq_end(lzma_outq *outq, lzma_allocator *allocator)
|
||||
lzma_outq_end(lzma_outq *outq, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_free(outq->bufs, allocator);
|
||||
outq->bufs = NULL;
|
||||
|
||||
@@ -87,12 +87,13 @@ extern uint64_t lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads);
|
||||
/// \return - LZMA_OK
|
||||
/// - LZMA_MEM_ERROR
|
||||
///
|
||||
extern lzma_ret lzma_outq_init(lzma_outq *outq, lzma_allocator *allocator,
|
||||
extern lzma_ret lzma_outq_init(
|
||||
lzma_outq *outq, const lzma_allocator *allocator,
|
||||
uint64_t buf_size_max, uint32_t threads);
|
||||
|
||||
|
||||
/// \brief Free the memory associated with the output queue
|
||||
extern void lzma_outq_end(lzma_outq *outq, lzma_allocator *allocator);
|
||||
extern void lzma_outq_end(lzma_outq *outq, const lzma_allocator *allocator);
|
||||
|
||||
|
||||
/// \brief Get a new buffer
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_stream_buffer_decode(uint64_t *memlimit, uint32_t flags,
|
||||
lzma_allocator *allocator,
|
||||
const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
|
||||
@@ -42,7 +42,8 @@ lzma_stream_buffer_bound(size_t uncompressed_size)
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_stream_buffer_encode(lzma_filter *filters, lzma_check check,
|
||||
lzma_allocator *allocator, const uint8_t *in, size_t in_size,
|
||||
const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos_ptr, size_t out_size)
|
||||
{
|
||||
// Sanity checks
|
||||
|
||||
@@ -80,7 +80,7 @@ struct lzma_coder_s {
|
||||
|
||||
|
||||
static lzma_ret
|
||||
stream_decoder_reset(lzma_coder *coder, lzma_allocator *allocator)
|
||||
stream_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
// Initialize the Index hash used to verify the Index.
|
||||
coder->index_hash = lzma_index_hash_init(coder->index_hash, allocator);
|
||||
@@ -96,7 +96,7 @@ stream_decoder_reset(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
stream_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
stream_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -366,7 +366,7 @@ stream_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static void
|
||||
stream_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
stream_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->block_decoder, allocator);
|
||||
lzma_index_hash_end(coder->index_hash, allocator);
|
||||
@@ -401,7 +401,8 @@ stream_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_stream_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_stream_decoder_init(
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
uint64_t memlimit, uint32_t flags)
|
||||
{
|
||||
lzma_next_coder_init(&lzma_stream_decoder_init, next, allocator);
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
extern lzma_ret lzma_stream_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, uint64_t memlimit, uint32_t flags);
|
||||
extern lzma_ret lzma_stream_decoder_init(
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
uint64_t memlimit, uint32_t flags);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -59,7 +59,7 @@ struct lzma_coder_s {
|
||||
|
||||
|
||||
static lzma_ret
|
||||
block_encoder_init(lzma_coder *coder, lzma_allocator *allocator)
|
||||
block_encoder_init(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
// Prepare the Block options. Even though Block encoder doesn't need
|
||||
// compressed_size, uncompressed_size, and header_size to be
|
||||
@@ -78,7 +78,7 @@ block_encoder_init(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
stream_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
stream_encode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -146,11 +146,12 @@ stream_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
}
|
||||
|
||||
case SEQ_BLOCK_ENCODE: {
|
||||
static const lzma_action convert[4] = {
|
||||
static const lzma_action convert[LZMA_ACTION_MAX + 1] = {
|
||||
LZMA_RUN,
|
||||
LZMA_SYNC_FLUSH,
|
||||
LZMA_FINISH,
|
||||
LZMA_FINISH,
|
||||
LZMA_FINISH,
|
||||
};
|
||||
|
||||
const lzma_ret ret = coder->block_encoder.code(
|
||||
@@ -208,7 +209,7 @@ stream_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static void
|
||||
stream_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
stream_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->block_encoder, allocator);
|
||||
lzma_next_end(&coder->index_encoder, allocator);
|
||||
@@ -223,7 +224,7 @@ stream_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
stream_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
stream_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters,
|
||||
const lzma_filter *reversed_filters)
|
||||
{
|
||||
@@ -262,7 +263,7 @@ stream_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
stream_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
stream_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters, lzma_check check)
|
||||
{
|
||||
lzma_next_coder_init(&stream_encoder_init, next, allocator);
|
||||
@@ -324,6 +325,7 @@ lzma_stream_encoder(lzma_stream *strm,
|
||||
strm->internal->supported_actions[LZMA_RUN] = true;
|
||||
strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
|
||||
strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
|
||||
strm->internal->supported_actions[LZMA_FULL_BARRIER] = true;
|
||||
strm->internal->supported_actions[LZMA_FINISH] = true;
|
||||
|
||||
return LZMA_OK;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "filter_encoder.h"
|
||||
#include "easy_preset.h"
|
||||
#include "block_encoder.h"
|
||||
#include "block_buffer_encoder.h"
|
||||
#include "index_encoder.h"
|
||||
#include "outqueue.h"
|
||||
|
||||
@@ -69,7 +70,13 @@ struct worker_thread_s {
|
||||
/// The allocator is set by the main thread. Since a copy of the
|
||||
/// pointer is kept here, the application must not change the
|
||||
/// allocator before calling lzma_end().
|
||||
lzma_allocator *allocator;
|
||||
const lzma_allocator *allocator;
|
||||
|
||||
/// Amount of uncompressed data that has already been compressed.
|
||||
uint64_t progress_in;
|
||||
|
||||
/// Amount of compressed data that is ready.
|
||||
uint64_t progress_out;
|
||||
|
||||
/// Block encoder
|
||||
lzma_next_coder block_encoder;
|
||||
@@ -80,12 +87,12 @@ struct worker_thread_s {
|
||||
/// Next structure in the stack of free worker threads.
|
||||
worker_thread *next;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
mythread_mutex mutex;
|
||||
mythread_cond cond;
|
||||
|
||||
/// The ID of this thread is used to join the thread
|
||||
/// when it's not needed anymore.
|
||||
pthread_t thread_id;
|
||||
mythread thread_id;
|
||||
};
|
||||
|
||||
|
||||
@@ -126,12 +133,9 @@ struct lzma_coder_s {
|
||||
lzma_outq outq;
|
||||
|
||||
|
||||
/// True if wait_max is used.
|
||||
bool has_timeout;
|
||||
|
||||
/// Maximum wait time if cannot use all the input and cannot
|
||||
/// fill the output buffer.
|
||||
struct timespec wait_max;
|
||||
/// fill the output buffer. This is in milliseconds.
|
||||
uint32_t timeout;
|
||||
|
||||
|
||||
/// Error code from a worker thread
|
||||
@@ -157,7 +161,17 @@ struct lzma_coder_s {
|
||||
/// the new input from the application.
|
||||
worker_thread *thr;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
/// Amount of uncompressed data in Blocks that have already
|
||||
/// been finished.
|
||||
uint64_t progress_in;
|
||||
|
||||
/// Amount of compressed data in Stream Header + Blocks that
|
||||
/// have already been finished.
|
||||
uint64_t progress_out;
|
||||
|
||||
|
||||
mythread_mutex mutex;
|
||||
mythread_cond cond;
|
||||
};
|
||||
|
||||
@@ -183,6 +197,9 @@ worker_error(worker_thread *thr, lzma_ret ret)
|
||||
static worker_state
|
||||
worker_encode(worker_thread *thr, worker_state state)
|
||||
{
|
||||
assert(thr->progress_in == 0);
|
||||
assert(thr->progress_out == 0);
|
||||
|
||||
// Set the Block options.
|
||||
thr->block_options = (lzma_block){
|
||||
.version = 0,
|
||||
@@ -221,17 +238,22 @@ worker_encode(worker_thread *thr, worker_state state)
|
||||
|
||||
do {
|
||||
mythread_sync(thr->mutex) {
|
||||
// Store in_pos and out_pos into *thr so that
|
||||
// an application may read them via
|
||||
// lzma_get_progress() to get progress information.
|
||||
//
|
||||
// NOTE: These aren't updated when the encoding
|
||||
// finishes. Instead, the final values are taken
|
||||
// later from thr->outbuf.
|
||||
thr->progress_in = in_pos;
|
||||
thr->progress_out = thr->outbuf->size;
|
||||
|
||||
while (in_size == thr->in_size
|
||||
&& thr->state == THR_RUN)
|
||||
pthread_cond_wait(&thr->cond, &thr->mutex);
|
||||
mythread_cond_wait(&thr->cond, &thr->mutex);
|
||||
|
||||
state = thr->state;
|
||||
in_size = thr->in_size;
|
||||
|
||||
// TODO? Store in_pos and out_pos into *thr here
|
||||
// so that the application may read them via
|
||||
// some currently non-existing function to get
|
||||
// progress information.
|
||||
}
|
||||
|
||||
// Return if we were asked to stop or exit.
|
||||
@@ -255,19 +277,55 @@ worker_encode(worker_thread *thr, worker_state state)
|
||||
thr->block_encoder.coder, thr->allocator,
|
||||
thr->in, &in_pos, in_limit, thr->outbuf->buf,
|
||||
&thr->outbuf->size, out_size, action);
|
||||
} while (ret == LZMA_OK);
|
||||
} while (ret == LZMA_OK && thr->outbuf->size < out_size);
|
||||
|
||||
if (ret != LZMA_STREAM_END) {
|
||||
worker_error(thr, ret);
|
||||
return THR_STOP;
|
||||
}
|
||||
switch (ret) {
|
||||
case LZMA_STREAM_END:
|
||||
assert(state == THR_FINISH);
|
||||
|
||||
assert(state == THR_FINISH);
|
||||
// Encode the Block Header. By doing it after
|
||||
// the compression, we can store the Compressed Size
|
||||
// and Uncompressed Size fields.
|
||||
ret = lzma_block_header_encode(&thr->block_options,
|
||||
thr->outbuf->buf);
|
||||
if (ret != LZMA_OK) {
|
||||
worker_error(thr, ret);
|
||||
return THR_STOP;
|
||||
}
|
||||
|
||||
// Encode the Block Header. By doing it after the compression,
|
||||
// we can store the Compressed Size and Uncompressed Size fields.
|
||||
ret = lzma_block_header_encode(&thr->block_options, thr->outbuf->buf);
|
||||
if (ret != LZMA_OK) {
|
||||
break;
|
||||
|
||||
case LZMA_OK:
|
||||
// The data was incompressible. Encode it using uncompressed
|
||||
// LZMA2 chunks.
|
||||
//
|
||||
// First wait that we have gotten all the input.
|
||||
mythread_sync(thr->mutex) {
|
||||
while (thr->state == THR_RUN)
|
||||
mythread_cond_wait(&thr->cond, &thr->mutex);
|
||||
|
||||
state = thr->state;
|
||||
in_size = thr->in_size;
|
||||
}
|
||||
|
||||
if (state >= THR_STOP)
|
||||
return state;
|
||||
|
||||
// Do the encoding. This takes care of the Block Header too.
|
||||
thr->outbuf->size = 0;
|
||||
ret = lzma_block_uncomp_encode(&thr->block_options,
|
||||
thr->in, in_size, thr->outbuf->buf,
|
||||
&thr->outbuf->size, out_size);
|
||||
|
||||
// It shouldn't fail.
|
||||
if (ret != LZMA_OK) {
|
||||
worker_error(thr, LZMA_PROG_ERROR);
|
||||
return THR_STOP;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
worker_error(thr, ret);
|
||||
return THR_STOP;
|
||||
}
|
||||
@@ -283,7 +341,7 @@ worker_encode(worker_thread *thr, worker_state state)
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
static MYTHREAD_RET_TYPE
|
||||
worker_start(void *thr_ptr)
|
||||
{
|
||||
worker_thread *thr = thr_ptr;
|
||||
@@ -297,14 +355,14 @@ worker_start(void *thr_ptr)
|
||||
// requested to stop, just set the state.
|
||||
if (thr->state == THR_STOP) {
|
||||
thr->state = THR_IDLE;
|
||||
pthread_cond_signal(&thr->cond);
|
||||
mythread_cond_signal(&thr->cond);
|
||||
}
|
||||
|
||||
state = thr->state;
|
||||
if (state != THR_IDLE)
|
||||
break;
|
||||
|
||||
pthread_cond_wait(&thr->cond, &thr->mutex);
|
||||
mythread_cond_wait(&thr->cond, &thr->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,11 +375,14 @@ worker_start(void *thr_ptr)
|
||||
if (state == THR_EXIT)
|
||||
break;
|
||||
|
||||
// Mark the thread as idle. Signal is needed for the case
|
||||
// Mark the thread as idle unless the main thread has
|
||||
// told us to exit. Signal is needed for the case
|
||||
// where the main thread is waiting for the threads to stop.
|
||||
mythread_sync(thr->mutex) {
|
||||
thr->state = THR_IDLE;
|
||||
pthread_cond_signal(&thr->cond);
|
||||
if (thr->state != THR_EXIT) {
|
||||
thr->state = THR_IDLE;
|
||||
mythread_cond_signal(&thr->cond);
|
||||
}
|
||||
}
|
||||
|
||||
mythread_sync(thr->coder->mutex) {
|
||||
@@ -329,6 +390,13 @@ worker_start(void *thr_ptr)
|
||||
// no errors occurred.
|
||||
thr->outbuf->finished = state == THR_FINISH;
|
||||
|
||||
// Update the main progress info.
|
||||
thr->coder->progress_in
|
||||
+= thr->outbuf->uncompressed_size;
|
||||
thr->coder->progress_out += thr->outbuf->size;
|
||||
thr->progress_in = 0;
|
||||
thr->progress_out = 0;
|
||||
|
||||
// Return this thread to the stack of free threads.
|
||||
thr->next = thr->coder->threads_free;
|
||||
thr->coder->threads_free = thr;
|
||||
@@ -338,35 +406,35 @@ worker_start(void *thr_ptr)
|
||||
}
|
||||
|
||||
// Exiting, free the resources.
|
||||
pthread_mutex_destroy(&thr->mutex);
|
||||
pthread_cond_destroy(&thr->cond);
|
||||
mythread_mutex_destroy(&thr->mutex);
|
||||
mythread_cond_destroy(&thr->cond);
|
||||
|
||||
lzma_next_end(&thr->block_encoder, thr->allocator);
|
||||
lzma_free(thr->in, thr->allocator);
|
||||
return NULL;
|
||||
return MYTHREAD_RET_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/// Make the threads stop but not exit. Optionally wait for them to stop.
|
||||
static void
|
||||
threads_stop(lzma_coder *coder, bool wait)
|
||||
threads_stop(lzma_coder *coder, bool wait_for_threads)
|
||||
{
|
||||
// Tell the threads to stop.
|
||||
for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
|
||||
mythread_sync(coder->threads[i].mutex) {
|
||||
coder->threads[i].state = THR_STOP;
|
||||
pthread_cond_signal(&coder->threads[i].cond);
|
||||
mythread_cond_signal(&coder->threads[i].cond);
|
||||
}
|
||||
}
|
||||
|
||||
if (!wait)
|
||||
if (!wait_for_threads)
|
||||
return;
|
||||
|
||||
// Wait for the threads to settle in the idle state.
|
||||
for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
|
||||
mythread_sync(coder->threads[i].mutex) {
|
||||
while (coder->threads[i].state != THR_IDLE)
|
||||
pthread_cond_wait(&coder->threads[i].cond,
|
||||
mythread_cond_wait(&coder->threads[i].cond,
|
||||
&coder->threads[i].mutex);
|
||||
}
|
||||
}
|
||||
@@ -378,17 +446,17 @@ threads_stop(lzma_coder *coder, bool wait)
|
||||
/// Stop the threads and free the resources associated with them.
|
||||
/// Wait until the threads have exited.
|
||||
static void
|
||||
threads_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
threads_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
|
||||
mythread_sync(coder->threads[i].mutex) {
|
||||
coder->threads[i].state = THR_EXIT;
|
||||
pthread_cond_signal(&coder->threads[i].cond);
|
||||
mythread_cond_signal(&coder->threads[i].cond);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
|
||||
int ret = pthread_join(coder->threads[i].thread_id, NULL);
|
||||
int ret = mythread_join(coder->threads[i].thread_id);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
}
|
||||
@@ -400,7 +468,7 @@ threads_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
/// Initialize a new worker_thread structure and create a new thread.
|
||||
static lzma_ret
|
||||
initialize_new_thread(lzma_coder *coder, lzma_allocator *allocator)
|
||||
initialize_new_thread(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
worker_thread *thr = &coder->threads[coder->threads_initialized];
|
||||
|
||||
@@ -408,15 +476,17 @@ initialize_new_thread(lzma_coder *coder, lzma_allocator *allocator)
|
||||
if (thr->in == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
if (pthread_mutex_init(&thr->mutex, NULL))
|
||||
if (mythread_mutex_init(&thr->mutex))
|
||||
goto error_mutex;
|
||||
|
||||
if (pthread_cond_init(&thr->cond, NULL))
|
||||
if (mythread_cond_init(&thr->cond))
|
||||
goto error_cond;
|
||||
|
||||
thr->state = THR_IDLE;
|
||||
thr->allocator = allocator;
|
||||
thr->coder = coder;
|
||||
thr->progress_in = 0;
|
||||
thr->progress_out = 0;
|
||||
thr->block_encoder = LZMA_NEXT_CODER_INIT;
|
||||
|
||||
if (mythread_create(&thr->thread_id, &worker_start, thr))
|
||||
@@ -428,10 +498,10 @@ initialize_new_thread(lzma_coder *coder, lzma_allocator *allocator)
|
||||
return LZMA_OK;
|
||||
|
||||
error_thread:
|
||||
pthread_cond_destroy(&thr->cond);
|
||||
mythread_cond_destroy(&thr->cond);
|
||||
|
||||
error_cond:
|
||||
pthread_mutex_destroy(&thr->mutex);
|
||||
mythread_mutex_destroy(&thr->mutex);
|
||||
|
||||
error_mutex:
|
||||
lzma_free(thr->in, allocator);
|
||||
@@ -440,7 +510,7 @@ error_mutex:
|
||||
|
||||
|
||||
static lzma_ret
|
||||
get_thread(lzma_coder *coder, lzma_allocator *allocator)
|
||||
get_thread(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
// If there are no free output subqueues, there is no
|
||||
// point to try getting a thread.
|
||||
@@ -470,7 +540,7 @@ get_thread(lzma_coder *coder, lzma_allocator *allocator)
|
||||
coder->thr->state = THR_RUN;
|
||||
coder->thr->in_size = 0;
|
||||
coder->thr->outbuf = lzma_outq_get_buf(&coder->outq);
|
||||
pthread_cond_signal(&coder->thr->cond);
|
||||
mythread_cond_signal(&coder->thr->cond);
|
||||
}
|
||||
|
||||
return LZMA_OK;
|
||||
@@ -478,7 +548,7 @@ get_thread(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
stream_encode_in(lzma_coder *coder, lzma_allocator *allocator,
|
||||
stream_encode_in(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, lzma_action action)
|
||||
{
|
||||
@@ -521,7 +591,7 @@ stream_encode_in(lzma_coder *coder, lzma_allocator *allocator,
|
||||
if (finish)
|
||||
coder->thr->state = THR_FINISH;
|
||||
|
||||
pthread_cond_signal(&coder->thr->cond);
|
||||
mythread_cond_signal(&coder->thr->cond);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,21 +616,20 @@ stream_encode_in(lzma_coder *coder, lzma_allocator *allocator,
|
||||
/// Wait until more input can be consumed, more output can be read, or
|
||||
/// an optional timeout is reached.
|
||||
static bool
|
||||
wait_for_work(lzma_coder *coder, struct timespec *wait_abs,
|
||||
wait_for_work(lzma_coder *coder, mythread_condtime *wait_abs,
|
||||
bool *has_blocked, bool has_input)
|
||||
{
|
||||
if (coder->has_timeout && !*has_blocked) {
|
||||
if (coder->timeout != 0 && !*has_blocked) {
|
||||
// Every time when stream_encode_mt() is called via
|
||||
// lzma_code(), *has_block starts as false. We set it
|
||||
// lzma_code(), *has_blocked starts as false. We set it
|
||||
// to true here and calculate the absolute time when
|
||||
// we must return if there's nothing to do.
|
||||
//
|
||||
// The idea of *has_blocked is to avoid unneeded calls
|
||||
// to mythread_cond_abstime(), which may do a syscall
|
||||
// to mythread_condtime_set(), which may do a syscall
|
||||
// depending on the operating system.
|
||||
*has_blocked = true;
|
||||
*wait_abs = coder->wait_max;
|
||||
mythread_cond_abstime(&coder->cond, wait_abs);
|
||||
mythread_condtime_set(wait_abs, &coder->cond, coder->timeout);
|
||||
}
|
||||
|
||||
bool timed_out = false;
|
||||
@@ -578,7 +647,7 @@ wait_for_work(lzma_coder *coder, struct timespec *wait_abs,
|
||||
&& !lzma_outq_is_readable(&coder->outq)
|
||||
&& coder->thread_error == LZMA_OK
|
||||
&& !timed_out) {
|
||||
if (coder->has_timeout)
|
||||
if (coder->timeout != 0)
|
||||
timed_out = mythread_cond_timedwait(
|
||||
&coder->cond, &coder->mutex,
|
||||
wait_abs) != 0;
|
||||
@@ -593,7 +662,7 @@ wait_for_work(lzma_coder *coder, struct timespec *wait_abs,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
stream_encode_mt(lzma_coder *coder, lzma_allocator *allocator,
|
||||
stream_encode_mt(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -619,7 +688,7 @@ stream_encode_mt(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
// These are for wait_for_work().
|
||||
bool has_blocked = false;
|
||||
struct timespec wait_abs;
|
||||
mythread_condtime wait_abs;
|
||||
|
||||
while (true) {
|
||||
mythread_sync(coder->mutex) {
|
||||
@@ -657,13 +726,6 @@ stream_encode_mt(lzma_coder *coder, lzma_allocator *allocator,
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check if the last Block was finished.
|
||||
if (action == LZMA_FINISH
|
||||
&& *in_pos == in_size
|
||||
&& lzma_outq_is_empty(
|
||||
&coder->outq))
|
||||
break;
|
||||
|
||||
// Try to give uncompressed data to a worker thread.
|
||||
ret = stream_encode_in(coder, allocator,
|
||||
in, in_pos, in_size, action);
|
||||
@@ -672,14 +734,44 @@ stream_encode_mt(lzma_coder *coder, lzma_allocator *allocator,
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Return if
|
||||
// - we have used all the input and expect to
|
||||
// get more input; or
|
||||
// - the output buffer has been filled.
|
||||
// See if we should wait or return.
|
||||
//
|
||||
// TODO: Support flushing.
|
||||
if ((*in_pos == in_size && action != LZMA_FINISH)
|
||||
|| *out_pos == out_size)
|
||||
// TODO: LZMA_SYNC_FLUSH and LZMA_SYNC_BARRIER.
|
||||
if (*in_pos == in_size) {
|
||||
// LZMA_RUN: More data is probably coming
|
||||
// so return to let the caller fill the
|
||||
// input buffer.
|
||||
if (action == LZMA_RUN)
|
||||
return LZMA_OK;
|
||||
|
||||
// LZMA_FULL_BARRIER: The same as with
|
||||
// LZMA_RUN but tell the caller that the
|
||||
// barrier was completed.
|
||||
if (action == LZMA_FULL_BARRIER)
|
||||
return LZMA_STREAM_END;
|
||||
|
||||
// Finishing or flushing isn't completed until
|
||||
// all input data has been encoded and copied
|
||||
// to the output buffer.
|
||||
if (lzma_outq_is_empty(&coder->outq)) {
|
||||
// LZMA_FINISH: Continue to encode
|
||||
// the Index field.
|
||||
if (action == LZMA_FINISH)
|
||||
break;
|
||||
|
||||
// LZMA_FULL_FLUSH: Return to tell
|
||||
// the caller that flushing was
|
||||
// completed.
|
||||
if (action == LZMA_FULL_FLUSH)
|
||||
return LZMA_STREAM_END;
|
||||
}
|
||||
}
|
||||
|
||||
// Return if there is no output space left.
|
||||
// This check must be done after testing the input
|
||||
// buffer, because we might want to use a different
|
||||
// return code.
|
||||
if (*out_pos == out_size)
|
||||
return LZMA_OK;
|
||||
|
||||
// Neither in nor out has been used completely.
|
||||
@@ -695,6 +787,13 @@ stream_encode_mt(lzma_coder *coder, lzma_allocator *allocator,
|
||||
&coder->index_encoder, allocator,
|
||||
coder->index));
|
||||
coder->sequence = SEQ_INDEX;
|
||||
|
||||
// Update the progress info to take the Index and
|
||||
// Stream Footer into account. Those are very fast to encode
|
||||
// so in terms of progress information they can be thought
|
||||
// to be ready to be copied out.
|
||||
coder->progress_out += lzma_index_size(coder->index)
|
||||
+ LZMA_STREAM_HEADER_SIZE;
|
||||
}
|
||||
|
||||
// Fall through
|
||||
@@ -735,7 +834,7 @@ stream_encode_mt(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static void
|
||||
stream_encoder_mt_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
stream_encoder_mt_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
// Threads must be killed before the output queue can be freed.
|
||||
threads_end(coder, allocator);
|
||||
@@ -748,7 +847,7 @@ stream_encoder_mt_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
lzma_index_end(coder->index, allocator);
|
||||
|
||||
mythread_cond_destroy(&coder->cond);
|
||||
pthread_mutex_destroy(&coder->mutex);
|
||||
mythread_mutex_destroy(&coder->mutex);
|
||||
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
@@ -799,19 +898,38 @@ get_options(const lzma_mt *options, lzma_options_easy *opt_easy,
|
||||
// Calculate the maximum amount output that a single output buffer
|
||||
// may need to hold. This is the same as the maximum total size of
|
||||
// a Block.
|
||||
//
|
||||
// FIXME: As long as the encoder keeps the whole input buffer
|
||||
// available and doesn't start writing output before finishing
|
||||
// the Block, it could use lzma_stream_buffer_bound() and use
|
||||
// uncompressed LZMA2 chunks if the data doesn't compress.
|
||||
*outbuf_size_max = *block_size + *block_size / 16 + 16384;
|
||||
*outbuf_size_max = lzma_block_buffer_bound64(*block_size);
|
||||
if (*outbuf_size_max == 0)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_progress(lzma_coder *coder, uint64_t *progress_in, uint64_t *progress_out)
|
||||
{
|
||||
// Lock coder->mutex to prevent finishing threads from moving their
|
||||
// progress info from the worker_thread structure to lzma_coder.
|
||||
mythread_sync(coder->mutex) {
|
||||
*progress_in = coder->progress_in;
|
||||
*progress_out = coder->progress_out;
|
||||
|
||||
for (size_t i = 0; i < coder->threads_initialized; ++i) {
|
||||
mythread_sync(coder->threads[i].mutex) {
|
||||
*progress_in += coder->threads[i].progress_in;
|
||||
*progress_out += coder->threads[i]
|
||||
.progress_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
stream_encoder_mt_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_mt *options)
|
||||
{
|
||||
lzma_next_coder_init(&stream_encoder_mt_init, next, allocator);
|
||||
@@ -850,14 +968,14 @@ stream_encoder_mt_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
// the error handling has to be done here because
|
||||
// stream_encoder_mt_end() doesn't know if they have
|
||||
// already been initialized or not.
|
||||
if (pthread_mutex_init(&next->coder->mutex, NULL)) {
|
||||
if (mythread_mutex_init(&next->coder->mutex)) {
|
||||
lzma_free(next->coder, allocator);
|
||||
next->coder = NULL;
|
||||
return LZMA_MEM_ERROR;
|
||||
}
|
||||
|
||||
if (mythread_cond_init(&next->coder->cond)) {
|
||||
pthread_mutex_destroy(&next->coder->mutex);
|
||||
mythread_mutex_destroy(&next->coder->mutex);
|
||||
lzma_free(next->coder, allocator);
|
||||
next->coder = NULL;
|
||||
return LZMA_MEM_ERROR;
|
||||
@@ -865,6 +983,7 @@ stream_encoder_mt_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
next->code = &stream_encode_mt;
|
||||
next->end = &stream_encoder_mt_end;
|
||||
next->get_progress = &get_progress;
|
||||
// next->update = &stream_encoder_mt_update;
|
||||
|
||||
next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
|
||||
@@ -911,14 +1030,7 @@ stream_encoder_mt_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
outbuf_size_max, options->threads));
|
||||
|
||||
// Timeout
|
||||
if (options->timeout > 0) {
|
||||
next->coder->wait_max.tv_sec = options->timeout / 1000;
|
||||
next->coder->wait_max.tv_nsec
|
||||
= (options->timeout % 1000) * 1000000L;
|
||||
next->coder->has_timeout = true;
|
||||
} else {
|
||||
next->coder->has_timeout = false;
|
||||
}
|
||||
next->coder->timeout = options->timeout;
|
||||
|
||||
// Free the old filter chain and copy the new one.
|
||||
for (size_t i = 0; next->coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
|
||||
@@ -941,6 +1053,10 @@ stream_encoder_mt_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
next->coder->header_pos = 0;
|
||||
|
||||
// Progress info
|
||||
next->coder->progress_in = 0;
|
||||
next->coder->progress_out = LZMA_STREAM_HEADER_SIZE;
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
@@ -952,8 +1068,8 @@ lzma_stream_encoder_mt(lzma_stream *strm, const lzma_mt *options)
|
||||
|
||||
strm->internal->supported_actions[LZMA_RUN] = true;
|
||||
// strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
|
||||
// strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
|
||||
// strm->internal->supported_actions[LZMA_FULL_BARRIER] = true;
|
||||
strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
|
||||
strm->internal->supported_actions[LZMA_FULL_BARRIER] = true;
|
||||
strm->internal->supported_actions[LZMA_FINISH] = true;
|
||||
|
||||
return LZMA_OK;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
static void
|
||||
delta_coder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
delta_coder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
@@ -24,7 +24,7 @@ delta_coder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_delta_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_delta_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
// Allocate memory for the decoder if needed.
|
||||
|
||||
@@ -27,7 +27,7 @@ decode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
delta_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
delta_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -47,7 +47,7 @@ delta_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_delta_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_delta_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
next->code = &delta_decode;
|
||||
@@ -56,7 +56,7 @@ lzma_delta_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_delta_props_decode(void **options, lzma_allocator *allocator,
|
||||
lzma_delta_props_decode(void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size)
|
||||
{
|
||||
if (props_size != 1)
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
#include "delta_common.h"
|
||||
|
||||
extern lzma_ret lzma_delta_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern lzma_ret lzma_delta_props_decode(
|
||||
void **options, lzma_allocator *allocator,
|
||||
void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@ encode_in_place(lzma_coder *coder, uint8_t *buffer, size_t size)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
delta_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
delta_encode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -84,7 +84,7 @@ delta_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
delta_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
delta_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters_null lzma_attribute((__unused__)),
|
||||
const lzma_filter *reversed_filters)
|
||||
{
|
||||
@@ -97,7 +97,7 @@ delta_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_delta_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_delta_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
next->code = &delta_encode;
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
#include "delta_common.h"
|
||||
|
||||
extern lzma_ret lzma_delta_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern lzma_ret lzma_delta_props_encode(const void *options, uint8_t *out);
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ struct lzma_coder_s {
|
||||
|
||||
|
||||
extern lzma_ret lzma_delta_coder_init(
|
||||
lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -95,8 +95,10 @@ global:
|
||||
lzma_vli_size;
|
||||
};
|
||||
|
||||
XZ_5.1.2alpha {
|
||||
XZ_5.1.3alpha {
|
||||
global:
|
||||
lzma_block_uncomp_encode;
|
||||
lzma_get_progress;
|
||||
lzma_stream_encoder_mt;
|
||||
lzma_stream_encoder_mt_memusage;
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ decode_buffer(lzma_coder *coder,
|
||||
|
||||
static lzma_ret
|
||||
lz_decode(lzma_coder *coder,
|
||||
lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size,
|
||||
@@ -184,7 +184,7 @@ lz_decode(lzma_coder *coder,
|
||||
|
||||
|
||||
static void
|
||||
lz_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
lz_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder->dict.buf, allocator);
|
||||
@@ -200,10 +200,10 @@ lz_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lz_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
lzma_ret (*lz_init)(lzma_lz_decoder *lz,
|
||||
lzma_allocator *allocator, const void *options,
|
||||
const lzma_allocator *allocator, const void *options,
|
||||
lzma_lz_options *lz_options))
|
||||
{
|
||||
// Allocate the base structure if it isn't already allocated.
|
||||
|
||||
@@ -67,7 +67,7 @@ typedef struct {
|
||||
lzma_vli uncompressed_size);
|
||||
|
||||
/// Free allocated resources
|
||||
void (*end)(lzma_coder *coder, lzma_allocator *allocator);
|
||||
void (*end)(lzma_coder *coder, const lzma_allocator *allocator);
|
||||
|
||||
} lzma_lz_decoder;
|
||||
|
||||
@@ -83,9 +83,10 @@ typedef struct {
|
||||
|
||||
|
||||
extern lzma_ret lzma_lz_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
lzma_ret (*lz_init)(lzma_lz_decoder *lz,
|
||||
lzma_allocator *allocator, const void *options,
|
||||
const lzma_allocator *allocator, const void *options,
|
||||
lzma_lz_options *lz_options));
|
||||
|
||||
extern uint64_t lzma_lz_decoder_memusage(size_t dictionary_size);
|
||||
|
||||
@@ -76,8 +76,9 @@ move_window(lzma_mf *mf)
|
||||
/// This function must not be called once it has returned LZMA_STREAM_END.
|
||||
///
|
||||
static lzma_ret
|
||||
fill_window(lzma_coder *coder, lzma_allocator *allocator, const uint8_t *in,
|
||||
size_t *in_pos, size_t in_size, lzma_action action)
|
||||
fill_window(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
lzma_action action)
|
||||
{
|
||||
assert(coder->mf.read_pos <= coder->mf.write_pos);
|
||||
|
||||
@@ -148,7 +149,7 @@ fill_window(lzma_coder *coder, lzma_allocator *allocator, const uint8_t *in,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lz_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
lz_encode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size,
|
||||
uint8_t *restrict out, size_t *restrict out_pos,
|
||||
@@ -179,7 +180,7 @@ lz_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static bool
|
||||
lz_encoder_prepare(lzma_mf *mf, lzma_allocator *allocator,
|
||||
lz_encoder_prepare(lzma_mf *mf, const lzma_allocator *allocator,
|
||||
const lzma_lz_options *lz_options)
|
||||
{
|
||||
// For now, the dictionary size is limited to 1.5 GiB. This may grow
|
||||
@@ -360,7 +361,7 @@ lz_encoder_prepare(lzma_mf *mf, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static bool
|
||||
lz_encoder_init(lzma_mf *mf, lzma_allocator *allocator,
|
||||
lz_encoder_init(lzma_mf *mf, const lzma_allocator *allocator,
|
||||
const lzma_lz_options *lz_options)
|
||||
{
|
||||
// Allocate the history buffer.
|
||||
@@ -461,7 +462,7 @@ lzma_lz_encoder_memusage(const lzma_lz_options *lz_options)
|
||||
|
||||
|
||||
static void
|
||||
lz_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
lz_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
|
||||
@@ -479,7 +480,7 @@ lz_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lz_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
lz_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters_null lzma_attribute((__unused__)),
|
||||
const lzma_filter *reversed_filters)
|
||||
{
|
||||
@@ -495,10 +496,10 @@ lz_encoder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lz_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_lz_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
lzma_ret (*lz_init)(lzma_lz_encoder *lz,
|
||||
lzma_allocator *allocator, const void *options,
|
||||
const lzma_allocator *allocator, const void *options,
|
||||
lzma_lz_options *lz_options))
|
||||
{
|
||||
#ifdef HAVE_SMALL
|
||||
|
||||
@@ -199,7 +199,7 @@ typedef struct {
|
||||
size_t *restrict out_pos, size_t out_size);
|
||||
|
||||
/// Free allocated resources
|
||||
void (*end)(lzma_coder *coder, lzma_allocator *allocator);
|
||||
void (*end)(lzma_coder *coder, const lzma_allocator *allocator);
|
||||
|
||||
/// Update the options in the middle of the encoding.
|
||||
lzma_ret (*options_update)(lzma_coder *coder,
|
||||
@@ -296,10 +296,10 @@ mf_read(lzma_mf *mf, uint8_t *out, size_t *out_pos, size_t out_size,
|
||||
|
||||
|
||||
extern lzma_ret lzma_lz_encoder_init(
|
||||
lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
lzma_ret (*lz_init)(lzma_lz_encoder *lz,
|
||||
lzma_allocator *allocator, const void *options,
|
||||
const lzma_allocator *allocator, const void *options,
|
||||
lzma_lz_options *lz_options));
|
||||
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ lzma2_decode(lzma_coder *restrict coder, lzma_dict *restrict dict,
|
||||
|
||||
|
||||
static void
|
||||
lzma2_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
lzma2_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
assert(coder->lzma.end == NULL);
|
||||
lzma_free(coder->lzma.coder, allocator);
|
||||
@@ -221,7 +221,7 @@ lzma2_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lzma2_decoder_init(lzma_lz_decoder *lz, lzma_allocator *allocator,
|
||||
lzma2_decoder_init(lzma_lz_decoder *lz, const lzma_allocator *allocator,
|
||||
const void *opt, lzma_lz_options *lz_options)
|
||||
{
|
||||
if (lz->coder == NULL) {
|
||||
@@ -248,7 +248,7 @@ lzma2_decoder_init(lzma_lz_decoder *lz, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma2_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_lzma2_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
// LZMA2 can only be the last filter in the chain. This is enforced
|
||||
@@ -269,7 +269,7 @@ lzma_lzma2_decoder_memusage(const void *options)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma2_props_decode(void **options, lzma_allocator *allocator,
|
||||
lzma_lzma2_props_decode(void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size)
|
||||
{
|
||||
if (props_size != 1)
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
#include "common.h"
|
||||
|
||||
extern lzma_ret lzma_lzma2_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern uint64_t lzma_lzma2_decoder_memusage(const void *options);
|
||||
|
||||
extern lzma_ret lzma_lzma2_props_decode(
|
||||
void **options, lzma_allocator *allocator,
|
||||
void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -262,7 +262,7 @@ lzma2_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
|
||||
|
||||
|
||||
static void
|
||||
lzma2_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
lzma2_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_free(coder->lzma, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
@@ -304,7 +304,7 @@ lzma2_encoder_options_update(lzma_coder *coder, const lzma_filter *filter)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lzma2_encoder_init(lzma_lz_encoder *lz, lzma_allocator *allocator,
|
||||
lzma2_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,
|
||||
const void *options, lzma_lz_options *lz_options)
|
||||
{
|
||||
if (options == NULL)
|
||||
@@ -349,7 +349,7 @@ lzma2_encoder_init(lzma_lz_encoder *lz, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma2_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_lzma2_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return lzma_lz_encoder_init(
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
|
||||
extern lzma_ret lzma_lzma2_encoder_init(
|
||||
lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern uint64_t lzma_lzma2_encoder_memusage(const void *options);
|
||||
|
||||
@@ -937,7 +937,7 @@ lzma_decoder_reset(lzma_coder *coder, const void *opt)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma_decoder_create(lzma_lz_decoder *lz, lzma_allocator *allocator,
|
||||
lzma_lzma_decoder_create(lzma_lz_decoder *lz, const lzma_allocator *allocator,
|
||||
const void *opt, lzma_lz_options *lz_options)
|
||||
{
|
||||
if (lz->coder == NULL) {
|
||||
@@ -965,7 +965,7 @@ lzma_lzma_decoder_create(lzma_lz_decoder *lz, lzma_allocator *allocator,
|
||||
/// initialization (lzma_lzma_decoder_init() passes function pointer to
|
||||
/// the LZ initialization).
|
||||
static lzma_ret
|
||||
lzma_decoder_init(lzma_lz_decoder *lz, lzma_allocator *allocator,
|
||||
lzma_decoder_init(lzma_lz_decoder *lz, const lzma_allocator *allocator,
|
||||
const void *options, lzma_lz_options *lz_options)
|
||||
{
|
||||
if (!is_lclppb_valid(options))
|
||||
@@ -982,7 +982,7 @@ lzma_decoder_init(lzma_lz_decoder *lz, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_lzma_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
// LZMA can only be the last filter in the chain. This is enforced
|
||||
@@ -1029,7 +1029,7 @@ lzma_lzma_decoder_memusage(const void *options)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma_props_decode(void **options, lzma_allocator *allocator,
|
||||
lzma_lzma_props_decode(void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size)
|
||||
{
|
||||
if (props_size != 5)
|
||||
|
||||
@@ -19,12 +19,13 @@
|
||||
|
||||
/// Allocates and initializes LZMA decoder
|
||||
extern lzma_ret lzma_lzma_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern uint64_t lzma_lzma_decoder_memusage(const void *options);
|
||||
|
||||
extern lzma_ret lzma_lzma_props_decode(
|
||||
void **options, lzma_allocator *allocator,
|
||||
void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size);
|
||||
|
||||
|
||||
@@ -40,7 +41,7 @@ extern bool lzma_lzma_lclppb_decode(
|
||||
/// Allocate and setup function pointers only. This is used by LZMA1 and
|
||||
/// LZMA2 decoders.
|
||||
extern lzma_ret lzma_lzma_decoder_create(
|
||||
lzma_lz_decoder *lz, lzma_allocator *allocator,
|
||||
lzma_lz_decoder *lz, const lzma_allocator *allocator,
|
||||
const void *opt, lzma_lz_options *lz_options);
|
||||
|
||||
/// Gets memory usage without validating lc/lp/pb. This is used by LZMA2
|
||||
|
||||
@@ -545,7 +545,8 @@ lzma_lzma_encoder_reset(lzma_coder *coder, const lzma_options_lzma *options)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma_encoder_create(lzma_coder **coder_ptr, lzma_allocator *allocator,
|
||||
lzma_lzma_encoder_create(lzma_coder **coder_ptr,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_options_lzma *options, lzma_lz_options *lz_options)
|
||||
{
|
||||
// Allocate lzma_coder if it wasn't already allocated.
|
||||
@@ -604,7 +605,7 @@ lzma_lzma_encoder_create(lzma_coder **coder_ptr, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lzma_encoder_init(lzma_lz_encoder *lz, lzma_allocator *allocator,
|
||||
lzma_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,
|
||||
const void *options, lzma_lz_options *lz_options)
|
||||
{
|
||||
lz->code = &lzma_encode;
|
||||
@@ -614,7 +615,7 @@ lzma_encoder_init(lzma_lz_encoder *lz, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_lzma_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return lzma_lz_encoder_init(
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
|
||||
extern lzma_ret lzma_lzma_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
|
||||
extern uint64_t lzma_lzma_encoder_memusage(const void *options);
|
||||
@@ -35,7 +36,7 @@ extern bool lzma_lzma_lclppb_encode(
|
||||
|
||||
/// Initializes raw LZMA encoder; this is used by LZMA2.
|
||||
extern lzma_ret lzma_lzma_encoder_create(
|
||||
lzma_coder **coder_ptr, lzma_allocator *allocator,
|
||||
lzma_coder **coder_ptr, const lzma_allocator *allocator,
|
||||
const lzma_options_lzma *options, lzma_lz_options *lz_options);
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ arm_code(lzma_simple *simple lzma_attribute((__unused__)),
|
||||
|
||||
|
||||
static lzma_ret
|
||||
arm_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
arm_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, bool is_encoder)
|
||||
{
|
||||
return lzma_simple_coder_init(next, allocator, filters,
|
||||
@@ -54,7 +54,8 @@ arm_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_arm_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_simple_arm_encoder_init(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return arm_coder_init(next, allocator, filters, true);
|
||||
@@ -62,7 +63,8 @@ lzma_simple_arm_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_arm_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_simple_arm_decoder_init(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return arm_coder_init(next, allocator, filters, false);
|
||||
|
||||
@@ -50,7 +50,7 @@ armthumb_code(lzma_simple *simple lzma_attribute((__unused__)),
|
||||
|
||||
|
||||
static lzma_ret
|
||||
armthumb_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
armthumb_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, bool is_encoder)
|
||||
{
|
||||
return lzma_simple_coder_init(next, allocator, filters,
|
||||
@@ -60,7 +60,8 @@ armthumb_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_armthumb_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters)
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return armthumb_coder_init(next, allocator, filters, true);
|
||||
}
|
||||
@@ -68,7 +69,8 @@ lzma_simple_armthumb_encoder_init(lzma_next_coder *next,
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_armthumb_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters)
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return armthumb_coder_init(next, allocator, filters, false);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ ia64_code(lzma_simple *simple lzma_attribute((__unused__)),
|
||||
|
||||
|
||||
static lzma_ret
|
||||
ia64_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
ia64_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, bool is_encoder)
|
||||
{
|
||||
return lzma_simple_coder_init(next, allocator, filters,
|
||||
@@ -96,7 +96,8 @@ ia64_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_ia64_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters)
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return ia64_coder_init(next, allocator, filters, true);
|
||||
}
|
||||
@@ -104,7 +105,8 @@ lzma_simple_ia64_encoder_init(lzma_next_coder *next,
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_ia64_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters)
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return ia64_coder_init(next, allocator, filters, false);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ powerpc_code(lzma_simple *simple lzma_attribute((__unused__)),
|
||||
|
||||
|
||||
static lzma_ret
|
||||
powerpc_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
powerpc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, bool is_encoder)
|
||||
{
|
||||
return lzma_simple_coder_init(next, allocator, filters,
|
||||
@@ -59,7 +59,8 @@ powerpc_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_powerpc_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters)
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return powerpc_coder_init(next, allocator, filters, true);
|
||||
}
|
||||
@@ -67,7 +68,8 @@ lzma_simple_powerpc_encoder_init(lzma_next_coder *next,
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_powerpc_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters)
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return powerpc_coder_init(next, allocator, filters, false);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
/// Copied or encodes/decodes more data to out[].
|
||||
static lzma_ret
|
||||
copy_or_code(lzma_coder *coder, lzma_allocator *allocator,
|
||||
copy_or_code(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -66,7 +66,7 @@ call_filter(lzma_coder *coder, uint8_t *buffer, size_t size)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
simple_code(lzma_coder *coder, lzma_allocator *allocator,
|
||||
simple_code(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
@@ -198,7 +198,7 @@ simple_code(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
static void
|
||||
simple_coder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
simple_coder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder->simple, allocator);
|
||||
@@ -208,7 +208,7 @@ simple_coder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
|
||||
|
||||
static lzma_ret
|
||||
simple_coder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
simple_coder_update(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters_null lzma_attribute((__unused__)),
|
||||
const lzma_filter *reversed_filters)
|
||||
{
|
||||
@@ -219,7 +219,7 @@ simple_coder_update(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_simple_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
|
||||
bool is_encoder, uint8_t *buffer, size_t size),
|
||||
|
||||
@@ -17,44 +17,56 @@
|
||||
|
||||
|
||||
extern lzma_ret lzma_simple_x86_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern lzma_ret lzma_simple_x86_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
|
||||
extern lzma_ret lzma_simple_powerpc_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern lzma_ret lzma_simple_powerpc_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
|
||||
extern lzma_ret lzma_simple_ia64_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern lzma_ret lzma_simple_ia64_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
|
||||
extern lzma_ret lzma_simple_arm_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern lzma_ret lzma_simple_arm_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
|
||||
extern lzma_ret lzma_simple_armthumb_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern lzma_ret lzma_simple_armthumb_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
|
||||
extern lzma_ret lzma_simple_sparc_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern lzma_ret lzma_simple_sparc_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_props_decode(void **options, lzma_allocator *allocator,
|
||||
lzma_simple_props_decode(void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size)
|
||||
{
|
||||
if (props_size == 0)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "simple_coder.h"
|
||||
|
||||
extern lzma_ret lzma_simple_props_decode(
|
||||
void **options, lzma_allocator *allocator,
|
||||
void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -66,7 +66,8 @@ struct lzma_coder_s {
|
||||
|
||||
|
||||
extern lzma_ret lzma_simple_coder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
|
||||
bool is_encoder, uint8_t *buffer, size_t size),
|
||||
size_t simple_size, size_t unfiltered_max,
|
||||
|
||||
@@ -57,7 +57,7 @@ sparc_code(lzma_simple *simple lzma_attribute((__unused__)),
|
||||
|
||||
|
||||
static lzma_ret
|
||||
sparc_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
sparc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, bool is_encoder)
|
||||
{
|
||||
return lzma_simple_coder_init(next, allocator, filters,
|
||||
@@ -67,7 +67,8 @@ sparc_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_sparc_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters)
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return sparc_coder_init(next, allocator, filters, true);
|
||||
}
|
||||
@@ -75,7 +76,8 @@ lzma_simple_sparc_encoder_init(lzma_next_coder *next,
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_sparc_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters)
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return sparc_coder_init(next, allocator, filters, false);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ x86_code(lzma_simple *simple, uint32_t now_pos, bool is_encoder,
|
||||
|
||||
|
||||
static lzma_ret
|
||||
x86_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
x86_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, bool is_encoder)
|
||||
{
|
||||
const lzma_ret ret = lzma_simple_coder_init(next, allocator, filters,
|
||||
@@ -139,7 +139,8 @@ x86_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_x86_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_simple_x86_encoder_init(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return x86_coder_init(next, allocator, filters, true);
|
||||
@@ -147,7 +148,8 @@ lzma_simple_x86_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_simple_x86_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_simple_x86_decoder_init(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return x86_coder_init(next, allocator, filters, false);
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
.\" This file has been put into the public domain.
|
||||
.\" You can do whatever you want with this file.
|
||||
.\"
|
||||
.TH LZMAINFO 1 "2010-09-27" "Tukaani" "XZ Utils"
|
||||
.TH LZMAINFO 1 "2013-06-30" "Tukaani" "XZ Utils"
|
||||
.SH NAME
|
||||
lzmainfo \- show information stored in the .lzma file header
|
||||
.SH SYNOPSIS
|
||||
.B lzmainfo
|
||||
.RB [ \-\-help ]
|
||||
.RB [ \-\-version ]
|
||||
.RI [ file ]...
|
||||
.RI [ file... ]
|
||||
.SH DESCRIPTION
|
||||
.B lzmainfo
|
||||
shows information stored in the
|
||||
|
||||
@@ -109,7 +109,7 @@ while test $# -ne 0; do
|
||||
files_with_matches=1;;
|
||||
(-L | --files-witho*)
|
||||
files_without_matches=1;;
|
||||
(--no-f*)
|
||||
(-h | --no-f*)
|
||||
no_filename=1;;
|
||||
(-V | --v | --ve | --ver | --vers | --versi | --versio | --version)
|
||||
echo "$version" || exit 2
|
||||
|
||||
@@ -46,7 +46,7 @@ if test "${LESSMETACHARS+set}" != set; then
|
||||
LESSMETACHARS="$space$tab$nl'"';*?"()<>[|&^`#\$%=~'
|
||||
fi
|
||||
|
||||
if test "$(less -V | { read ver && echo ${ver#less }; })" -ge 429; then
|
||||
if test "$(less -V | { read less ver re && echo ${ver}; })" -ge 429; then
|
||||
# less 429 or later: LESSOPEN pipe will be used on
|
||||
# standard input if $LESSOPEN begins with |-.
|
||||
LESSOPEN="|-$xz -cdfq -- %s"
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
.\"
|
||||
.\" License: GNU GPLv2+
|
||||
.\"
|
||||
.TH XZMORE 1 "2010-09-27" "Tukaani" "XZ Utils"
|
||||
.TH XZMORE 1 "2013-06-30" "Tukaani" "XZ Utils"
|
||||
.SH NAME
|
||||
xzmore, lzmore \- view xz or lzma compressed (text) files
|
||||
.SH SYNOPSIS
|
||||
.B xzmore
|
||||
.RI [ "filename ..." ]
|
||||
.RI [ file... ]
|
||||
.br
|
||||
.B lzmore
|
||||
.RI [ "filename ..." ]
|
||||
.RI [ file... ]
|
||||
.SH DESCRIPTION
|
||||
.B xzmore
|
||||
is a filter which allows examination of
|
||||
|
||||
@@ -22,6 +22,8 @@ xz_SOURCES = \
|
||||
main.h \
|
||||
message.c \
|
||||
message.h \
|
||||
mytime.c \
|
||||
mytime.h \
|
||||
options.c \
|
||||
options.h \
|
||||
private.h \
|
||||
|
||||
@@ -140,6 +140,7 @@ parse_real(args_info *args, int argc, char **argv)
|
||||
OPT_NO_ADJUST,
|
||||
OPT_INFO_MEMORY,
|
||||
OPT_ROBOT,
|
||||
OPT_FLUSH_TIMEOUT,
|
||||
};
|
||||
|
||||
static const char short_opts[]
|
||||
@@ -176,6 +177,7 @@ parse_real(args_info *args, int argc, char **argv)
|
||||
{ "memory", required_argument, NULL, 'M' }, // Old alias
|
||||
{ "no-adjust", no_argument, NULL, OPT_NO_ADJUST },
|
||||
{ "threads", required_argument, NULL, 'T' },
|
||||
{ "flush-timeout", required_argument, NULL, OPT_FLUSH_TIMEOUT },
|
||||
|
||||
{ "extreme", no_argument, NULL, 'e' },
|
||||
{ "fast", no_argument, NULL, '0' },
|
||||
@@ -483,6 +485,11 @@ parse_real(args_info *args, int argc, char **argv)
|
||||
opt_auto_adjust = false;
|
||||
break;
|
||||
|
||||
case OPT_FLUSH_TIMEOUT:
|
||||
opt_flush_timeout = str_to_uint64("flush-timeout",
|
||||
optarg, 0, UINT64_MAX);
|
||||
break;
|
||||
|
||||
default:
|
||||
message_try_help();
|
||||
tuklib_exit(E_ERROR, E_ERROR, false);
|
||||
|
||||
@@ -43,12 +43,7 @@ static io_buf out_buf;
|
||||
static uint32_t filters_count = 0;
|
||||
|
||||
/// Number of the preset (0-9)
|
||||
static uint32_t preset_number = 6;
|
||||
|
||||
/// If a preset is used (no custom filter chain) and preset_extreme is true,
|
||||
/// a significantly slower compression is used to achieve slightly better
|
||||
/// compression ratio.
|
||||
static bool preset_extreme = false;
|
||||
static uint32_t preset_number = LZMA_PRESET_DEFAULT;
|
||||
|
||||
/// Integrity check type
|
||||
static lzma_check check;
|
||||
@@ -56,7 +51,7 @@ static lzma_check check;
|
||||
/// This becomes false if the --check=CHECK option is used.
|
||||
static bool check_default = true;
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
#ifdef MYTHREAD_ENABLED
|
||||
static lzma_mt mt_options = {
|
||||
.flags = 0,
|
||||
.timeout = 300,
|
||||
@@ -74,11 +69,9 @@ coder_set_check(lzma_check new_check)
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
coder_set_preset(uint32_t new_preset)
|
||||
static void
|
||||
forget_filter_chain(void)
|
||||
{
|
||||
preset_number = new_preset;
|
||||
|
||||
// Setting a preset makes us forget a possibly defined custom
|
||||
// filter chain.
|
||||
while (filters_count > 0) {
|
||||
@@ -91,10 +84,21 @@ coder_set_preset(uint32_t new_preset)
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
coder_set_preset(uint32_t new_preset)
|
||||
{
|
||||
preset_number &= ~LZMA_PRESET_LEVEL_MASK;
|
||||
preset_number |= new_preset;
|
||||
forget_filter_chain();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
coder_set_extreme(void)
|
||||
{
|
||||
preset_extreme = true;
|
||||
preset_number |= LZMA_PRESET_EXTREME;
|
||||
forget_filter_chain();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -109,6 +113,12 @@ coder_add_filter(lzma_vli id, void *options)
|
||||
filters[filters_count].options = options;
|
||||
++filters_count;
|
||||
|
||||
// Setting a custom filter chain makes us forget the preset options.
|
||||
// This makes a difference if one specifies e.g. "xz -9 --lzma2 -e"
|
||||
// where the custom filter chain resets the preset level back to
|
||||
// the default 6, making the example equivalent to "xz -6e".
|
||||
preset_number = LZMA_PRESET_DEFAULT;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -154,9 +164,6 @@ coder_set_compression_settings(void)
|
||||
}
|
||||
|
||||
// Get the preset for LZMA1 or LZMA2.
|
||||
if (preset_extreme)
|
||||
preset_number |= LZMA_PRESET_EXTREME;
|
||||
|
||||
if (lzma_lzma_preset(&opt_lzma, preset_number))
|
||||
message_bug();
|
||||
|
||||
@@ -193,7 +200,7 @@ coder_set_compression_settings(void)
|
||||
const uint64_t memory_limit = hardware_memlimit_get(opt_mode);
|
||||
uint64_t memory_usage;
|
||||
if (opt_mode == MODE_COMPRESS) {
|
||||
#ifdef HAVE_PTHREAD
|
||||
#ifdef MYTHREAD_ENABLED
|
||||
if (opt_format == FORMAT_XZ && hardware_threads_get() > 1) {
|
||||
mt_options.threads = hardware_threads_get();
|
||||
mt_options.block_size = opt_block_size;
|
||||
@@ -238,7 +245,7 @@ coder_set_compression_settings(void)
|
||||
|
||||
assert(opt_mode == MODE_COMPRESS);
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
#ifdef MYTHREAD_ENABLED
|
||||
if (opt_format == FORMAT_XZ && mt_options.threads > 1) {
|
||||
// Try to reduce the number of threads before
|
||||
// adjusting the compression settings down.
|
||||
@@ -401,7 +408,7 @@ coder_init(file_pair *pair)
|
||||
break;
|
||||
|
||||
case FORMAT_XZ:
|
||||
#ifdef HAVE_PTHREAD
|
||||
#ifdef MYTHREAD_ENABLED
|
||||
if (hardware_threads_get() > 1)
|
||||
ret = lzma_stream_encoder_mt(
|
||||
&strm, &mt_options);
|
||||
@@ -558,9 +565,9 @@ coder_normal(file_pair *pair)
|
||||
strm.avail_out = IO_BUFFER_SIZE;
|
||||
|
||||
while (!user_abort) {
|
||||
// Fill the input buffer if it is empty and we haven't reached
|
||||
// end of file yet.
|
||||
if (strm.avail_in == 0 && !pair->src_eof) {
|
||||
// Fill the input buffer if it is empty and we aren't
|
||||
// flushing or finishing.
|
||||
if (strm.avail_in == 0 && action == LZMA_RUN) {
|
||||
strm.next_in = in_buf.u8;
|
||||
strm.avail_in = io_read(pair, &in_buf,
|
||||
my_min(block_remaining,
|
||||
@@ -577,8 +584,11 @@ coder_normal(file_pair *pair)
|
||||
// opt_block_size bytes of input.
|
||||
block_remaining -= strm.avail_in;
|
||||
if (block_remaining == 0)
|
||||
action = LZMA_FULL_FLUSH;
|
||||
action = LZMA_FULL_BARRIER;
|
||||
}
|
||||
|
||||
if (action == LZMA_RUN && flush_needed)
|
||||
action = LZMA_SYNC_FLUSH;
|
||||
}
|
||||
|
||||
// Let liblzma do the actual work.
|
||||
@@ -594,21 +604,40 @@ coder_normal(file_pair *pair)
|
||||
strm.avail_out = IO_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (ret == LZMA_STREAM_END && action == LZMA_FULL_FLUSH) {
|
||||
// Start a new Block.
|
||||
action = LZMA_RUN;
|
||||
if (ret == LZMA_STREAM_END && (action == LZMA_SYNC_FLUSH
|
||||
|| action == LZMA_FULL_BARRIER)) {
|
||||
if (action == LZMA_SYNC_FLUSH) {
|
||||
// Flushing completed. Write the pending data
|
||||
// out immediatelly so that the reading side
|
||||
// can decompress everything compressed so far.
|
||||
if (io_write(pair, &out_buf, IO_BUFFER_SIZE
|
||||
- strm.avail_out))
|
||||
break;
|
||||
|
||||
if (opt_block_list == NULL) {
|
||||
block_remaining = opt_block_size;
|
||||
strm.next_out = out_buf.u8;
|
||||
strm.avail_out = IO_BUFFER_SIZE;
|
||||
|
||||
// Set the time of the most recent flushing.
|
||||
mytime_set_flush_time();
|
||||
} else {
|
||||
// FIXME: Make it work together with
|
||||
// --block-size.
|
||||
if (opt_block_list[list_pos + 1] != 0)
|
||||
++list_pos;
|
||||
// Start a new Block after LZMA_FULL_BARRIER.
|
||||
if (opt_block_list == NULL) {
|
||||
block_remaining = opt_block_size;
|
||||
} else {
|
||||
// FIXME: Make it work together with
|
||||
// --block-size.
|
||||
if (opt_block_list[list_pos + 1] != 0)
|
||||
++list_pos;
|
||||
|
||||
block_remaining = opt_block_list[list_pos];
|
||||
block_remaining
|
||||
= opt_block_list[list_pos];
|
||||
}
|
||||
}
|
||||
|
||||
// Start a new Block after LZMA_FULL_FLUSH or continue
|
||||
// the same block after LZMA_SYNC_FLUSH.
|
||||
action = LZMA_RUN;
|
||||
|
||||
} else if (ret != LZMA_OK) {
|
||||
// Determine if the return value indicates that we
|
||||
// won't continue coding.
|
||||
@@ -759,6 +788,11 @@ coder_run(const char *filename)
|
||||
// Don't open the destination file when --test
|
||||
// is used.
|
||||
if (opt_mode == MODE_TEST || !io_open_dest(pair)) {
|
||||
// Remember the current time. It is needed
|
||||
// for progress indicator and for timed
|
||||
// flushing.
|
||||
mytime_set_start_time();
|
||||
|
||||
// Initialize the progress indicator.
|
||||
const uint64_t in_size
|
||||
= pair->src_st.st_size <= 0
|
||||
|
||||
318
src/xz/file_io.c
318
src/xz/file_io.c
@@ -17,6 +17,7 @@
|
||||
#ifdef TUKLIB_DOSLIKE
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <poll.h>
|
||||
static bool warn_fchown;
|
||||
#endif
|
||||
|
||||
@@ -37,13 +38,30 @@ static bool warn_fchown;
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum {
|
||||
IO_WAIT_MORE, // Reading or writing is possible.
|
||||
IO_WAIT_ERROR, // Error or user_abort
|
||||
IO_WAIT_TIMEOUT, // poll() timed out
|
||||
} io_wait_ret;
|
||||
|
||||
|
||||
/// If true, try to create sparse files when decompressing.
|
||||
static bool try_sparse = true;
|
||||
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
/// File status flags of standard output. This is used by io_open_dest()
|
||||
/// and io_close_dest().
|
||||
static int stdout_flags = 0;
|
||||
/// File status flags of standard input. This is used by io_open_src()
|
||||
/// and io_close_src().
|
||||
static int stdin_flags;
|
||||
static bool restore_stdin_flags = false;
|
||||
|
||||
/// Original file status flags of standard output. This is used by
|
||||
/// io_open_dest() and io_close_dest() to save and restore the flags.
|
||||
static int stdout_flags;
|
||||
static bool restore_stdout_flags = false;
|
||||
|
||||
/// Self-pipe used together with the user_abort variable to avoid
|
||||
/// race conditions with signal handling.
|
||||
static int user_abort_pipe[2];
|
||||
#endif
|
||||
|
||||
|
||||
@@ -63,6 +81,14 @@ io_init(void)
|
||||
// If fchown() fails setting the owner, we warn about it only if
|
||||
// we are root.
|
||||
warn_fchown = geteuid() == 0;
|
||||
|
||||
if (pipe(user_abort_pipe)
|
||||
|| fcntl(user_abort_pipe[0], F_SETFL, O_NONBLOCK)
|
||||
== -1
|
||||
|| fcntl(user_abort_pipe[1], F_SETFL, O_NONBLOCK)
|
||||
== -1)
|
||||
message_fatal(_("Error creating a pipe: %s"),
|
||||
strerror(errno));
|
||||
#endif
|
||||
|
||||
#ifdef __DJGPP__
|
||||
@@ -75,6 +101,23 @@ io_init(void)
|
||||
}
|
||||
|
||||
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
extern void
|
||||
io_write_to_user_abort_pipe(void)
|
||||
{
|
||||
// If the write() fails, it's probably due to the pipe being full.
|
||||
// Failing in that case is fine. If the reason is something else,
|
||||
// there's not much we can do since this is called in a signal
|
||||
// handler. So ignore the errors and try to avoid warnings with
|
||||
// GCC and glibc when _FORTIFY_SOURCE=2 is used.
|
||||
uint8_t b = '\0';
|
||||
const int ret = write(user_abort_pipe[1], &b, 1);
|
||||
(void)ret;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
extern void
|
||||
io_no_sparse(void)
|
||||
{
|
||||
@@ -83,6 +126,63 @@ io_no_sparse(void)
|
||||
}
|
||||
|
||||
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
/// \brief Waits for input or output to become available or for a signal
|
||||
///
|
||||
/// This uses the self-pipe trick to avoid a race condition that can occur
|
||||
/// if a signal is caught after user_abort has been checked but before e.g.
|
||||
/// read() has been called. In that situation read() could block unless
|
||||
/// non-blocking I/O is used. With non-blocking I/O something like select()
|
||||
/// or poll() is needed to avoid a busy-wait loop, and the same race condition
|
||||
/// pops up again. There are pselect() (POSIX-1.2001) and ppoll() (not in
|
||||
/// POSIX) but neither is portable enough in 2013. The self-pipe trick is
|
||||
/// old and very portable.
|
||||
static io_wait_ret
|
||||
io_wait(file_pair *pair, int timeout, bool is_reading)
|
||||
{
|
||||
struct pollfd pfd[2];
|
||||
|
||||
if (is_reading) {
|
||||
pfd[0].fd = pair->src_fd;
|
||||
pfd[0].events = POLLIN;
|
||||
} else {
|
||||
pfd[0].fd = pair->dest_fd;
|
||||
pfd[0].events = POLLOUT;
|
||||
}
|
||||
|
||||
pfd[1].fd = user_abort_pipe[0];
|
||||
pfd[1].events = POLLIN;
|
||||
|
||||
while (true) {
|
||||
const int ret = poll(pfd, 2, timeout);
|
||||
|
||||
if (user_abort)
|
||||
return IO_WAIT_ERROR;
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
|
||||
message_error(_("%s: poll() failed: %s"),
|
||||
is_reading ? pair->src_name
|
||||
: pair->dest_name,
|
||||
strerror(errno));
|
||||
return IO_WAIT_ERROR;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
assert(opt_flush_timeout != 0);
|
||||
flush_needed = true;
|
||||
return IO_WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
if (pfd[0].revents != 0)
|
||||
return IO_WAIT_MORE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/// \brief Unlink a file
|
||||
///
|
||||
/// This tries to verify that the file being unlinked really is the file that
|
||||
@@ -292,6 +392,27 @@ io_open_src_real(file_pair *pair)
|
||||
pair->src_fd = STDIN_FILENO;
|
||||
#ifdef TUKLIB_DOSLIKE
|
||||
setmode(STDIN_FILENO, O_BINARY);
|
||||
#else
|
||||
// Enable O_NONBLOCK for stdin.
|
||||
stdin_flags = fcntl(STDIN_FILENO, F_GETFL);
|
||||
if (stdin_flags == -1) {
|
||||
message_error(_("Error getting the file status flags "
|
||||
"from standard input: %s"),
|
||||
strerror(errno));
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((stdin_flags & O_NONBLOCK) == 0) {
|
||||
if (fcntl(STDIN_FILENO, F_SETFL,
|
||||
stdin_flags | O_NONBLOCK) == -1) {
|
||||
message_error(_("Error setting O_NONBLOCK "
|
||||
"on standard input: %s"),
|
||||
strerror(errno));
|
||||
return true;
|
||||
}
|
||||
|
||||
restore_stdin_flags = true;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_POSIX_FADVISE
|
||||
// It will fail if stdin is a pipe and that's fine.
|
||||
@@ -313,13 +434,12 @@ io_open_src_real(file_pair *pair)
|
||||
int flags = O_RDONLY | O_BINARY | O_NOCTTY;
|
||||
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
// If we accept only regular files, we need to be careful to avoid
|
||||
// problems with special files like devices and FIFOs. O_NONBLOCK
|
||||
// prevents blocking when opening such files. When we want to accept
|
||||
// special files, we must not use O_NONBLOCK, or otherwise we won't
|
||||
// block waiting e.g. FIFOs to become readable.
|
||||
if (reg_files_only)
|
||||
flags |= O_NONBLOCK;
|
||||
// Use non-blocking I/O:
|
||||
// - It prevents blocking when opening FIFOs and some other
|
||||
// special files, which is good if we want to accept only
|
||||
// regular files.
|
||||
// - It can help avoiding some race conditions with signal handling.
|
||||
flags |= O_NONBLOCK;
|
||||
#endif
|
||||
|
||||
#if defined(O_NOFOLLOW)
|
||||
@@ -347,30 +467,13 @@ io_open_src_real(file_pair *pair)
|
||||
(void)follow_symlinks;
|
||||
#endif
|
||||
|
||||
// Try to open the file. If we are accepting non-regular files,
|
||||
// unblock the caught signals so that open() can be interrupted
|
||||
// if it blocks e.g. due to a FIFO file.
|
||||
if (!reg_files_only)
|
||||
signals_unblock();
|
||||
|
||||
// Maybe this wouldn't need a loop, since all the signal handlers for
|
||||
// which we don't use SA_RESTART set user_abort to true. But it
|
||||
// doesn't hurt to have it just in case.
|
||||
do {
|
||||
pair->src_fd = open(pair->src_name, flags);
|
||||
} while (pair->src_fd == -1 && errno == EINTR && !user_abort);
|
||||
|
||||
if (!reg_files_only)
|
||||
signals_block();
|
||||
// Try to open the file. Signals have been blocked so EINTR shouldn't
|
||||
// be possible.
|
||||
pair->src_fd = open(pair->src_name, flags);
|
||||
|
||||
if (pair->src_fd == -1) {
|
||||
// If we were interrupted, don't display any error message.
|
||||
if (errno == EINTR) {
|
||||
// All the signals that don't have SA_RESTART
|
||||
// set user_abort.
|
||||
assert(user_abort);
|
||||
return true;
|
||||
}
|
||||
// Signals (that have a signal handler) have been blocked.
|
||||
assert(errno != EINTR);
|
||||
|
||||
#ifdef O_NOFOLLOW
|
||||
// Give an understandable error message if the reason
|
||||
@@ -400,10 +503,6 @@ io_open_src_real(file_pair *pair)
|
||||
was_symlink = true;
|
||||
|
||||
# elif defined(__NetBSD__)
|
||||
// As of 2010-09-05, NetBSD doesn't document what errno is
|
||||
// used with O_NOFOLLOW. It is EFTYPE though, and I
|
||||
// understood that is very unlikely to change even though
|
||||
// it is undocumented.
|
||||
if (errno == EFTYPE)
|
||||
was_symlink = true;
|
||||
|
||||
@@ -433,22 +532,6 @@ io_open_src_real(file_pair *pair)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
// Drop O_NONBLOCK, which is used only when we are accepting only
|
||||
// regular files. After the open() call, we want things to block
|
||||
// instead of giving EAGAIN.
|
||||
if (reg_files_only) {
|
||||
flags = fcntl(pair->src_fd, F_GETFL);
|
||||
if (flags == -1)
|
||||
goto error_msg;
|
||||
|
||||
flags &= ~O_NONBLOCK;
|
||||
|
||||
if (fcntl(pair->src_fd, F_SETFL, flags))
|
||||
goto error_msg;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Stat the source file. We need the result also when we copy
|
||||
// the permissions, and when unlinking.
|
||||
//
|
||||
@@ -508,17 +591,23 @@ io_open_src_real(file_pair *pair)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
// If it is something else than a regular file, wait until
|
||||
// there is input available. This way reading from FIFOs
|
||||
// will work when open() is used with O_NONBLOCK.
|
||||
if (!S_ISREG(pair->src_st.st_mode)) {
|
||||
signals_unblock();
|
||||
const io_wait_ret ret = io_wait(pair, -1, true);
|
||||
signals_block();
|
||||
|
||||
if (ret != IO_WAIT_MORE)
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_POSIX_FADVISE
|
||||
const int fadvise_ret = posix_fadvise(
|
||||
pair->src_fd, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
|
||||
// It shouldn't fail, but if it does anyway, it doesn't matter.
|
||||
// Check it with an assertion so that if something gets messed
|
||||
// up in the future, it will get caught when debugging is enabled.
|
||||
assert(fadvise_ret == 0);
|
||||
(void)fadvise_ret;
|
||||
// It will fail with some special files like FIFOs but that is fine.
|
||||
(void)posix_fadvise(pair->src_fd, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
@@ -569,6 +658,19 @@ io_open_src(const char *src_name)
|
||||
static void
|
||||
io_close_src(file_pair *pair, bool success)
|
||||
{
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
if (restore_stdin_flags) {
|
||||
assert(pair->src_fd == STDIN_FILENO);
|
||||
|
||||
restore_stdin_flags = false;
|
||||
|
||||
if (fcntl(STDIN_FILENO, F_SETFL, stdin_flags) == -1)
|
||||
message_error(_("Error restoring the status flags "
|
||||
"to standard input: %s"),
|
||||
strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pair->src_fd != STDIN_FILENO && pair->src_fd != -1) {
|
||||
#ifdef TUKLIB_DOSLIKE
|
||||
(void)close(pair->src_fd);
|
||||
@@ -602,6 +704,30 @@ io_open_dest_real(file_pair *pair)
|
||||
pair->dest_fd = STDOUT_FILENO;
|
||||
#ifdef TUKLIB_DOSLIKE
|
||||
setmode(STDOUT_FILENO, O_BINARY);
|
||||
#else
|
||||
// Set O_NONBLOCK if it isn't already set.
|
||||
//
|
||||
// NOTE: O_APPEND may be unset later in this function
|
||||
// and it relies on stdout_flags being set here.
|
||||
stdout_flags = fcntl(STDOUT_FILENO, F_GETFL);
|
||||
if (stdout_flags == -1) {
|
||||
message_error(_("Error getting the file status flags "
|
||||
"from standard output: %s"),
|
||||
strerror(errno));
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((stdout_flags & O_NONBLOCK) == 0) {
|
||||
if (fcntl(STDOUT_FILENO, F_SETFL,
|
||||
stdout_flags | O_NONBLOCK) == -1) {
|
||||
message_error(_("Error setting O_NONBLOCK "
|
||||
"on standard output: %s"),
|
||||
strerror(errno));
|
||||
return true;
|
||||
}
|
||||
|
||||
restore_stdout_flags = true;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
pair->dest_name = suffix_get_dest_name(pair->src_name);
|
||||
@@ -639,8 +765,11 @@ io_open_dest_real(file_pair *pair)
|
||||
}
|
||||
|
||||
// Open the file.
|
||||
const int flags = O_WRONLY | O_BINARY | O_NOCTTY
|
||||
int flags = O_WRONLY | O_BINARY | O_NOCTTY
|
||||
| O_CREAT | O_EXCL;
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
flags |= O_NONBLOCK;
|
||||
#endif
|
||||
const mode_t mode = S_IRUSR | S_IWUSR;
|
||||
pair->dest_fd = open(pair->dest_name, flags, mode);
|
||||
|
||||
@@ -682,11 +811,7 @@ io_open_dest_real(file_pair *pair)
|
||||
if (!S_ISREG(pair->dest_st.st_mode))
|
||||
return false;
|
||||
|
||||
const int flags = fcntl(STDOUT_FILENO, F_GETFL);
|
||||
if (flags == -1)
|
||||
return false;
|
||||
|
||||
if (flags & O_APPEND) {
|
||||
if (stdout_flags & O_APPEND) {
|
||||
// Creating a sparse file is not possible
|
||||
// when O_APPEND is active (it's used by
|
||||
// shell's >> redirection). As I understand
|
||||
@@ -704,13 +829,24 @@ io_open_dest_real(file_pair *pair)
|
||||
if (lseek(STDOUT_FILENO, 0, SEEK_END) == -1)
|
||||
return false;
|
||||
|
||||
// O_NONBLOCK was set earlier in this function
|
||||
// so it must be kept here too. If this
|
||||
// fcntl() call fails, we continue but won't
|
||||
// try to create sparse output. The original
|
||||
// flags will still be restored if needed (to
|
||||
// unset O_NONBLOCK) when the file is finished.
|
||||
if (fcntl(STDOUT_FILENO, F_SETFL,
|
||||
stdout_flags & ~O_APPEND))
|
||||
(stdout_flags | O_NONBLOCK)
|
||||
& ~O_APPEND) == -1)
|
||||
return false;
|
||||
|
||||
// Remember the flags so that io_close_dest()
|
||||
// can restore them.
|
||||
stdout_flags = flags;
|
||||
// Disabling O_APPEND succeeded. Mark
|
||||
// that the flags should be restored
|
||||
// in io_close_dest(). This quite likely was
|
||||
// already set when enabling O_NONBLOCK but
|
||||
// just in case O_NONBLOCK was already set,
|
||||
// set this again here.
|
||||
restore_stdout_flags = true;
|
||||
|
||||
} else if (lseek(STDOUT_FILENO, 0, SEEK_CUR)
|
||||
!= pair->dest_st.st_size) {
|
||||
@@ -751,13 +887,12 @@ io_close_dest(file_pair *pair, bool success)
|
||||
{
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
// If io_open_dest() has disabled O_APPEND, restore it here.
|
||||
if (stdout_flags != 0) {
|
||||
if (restore_stdout_flags) {
|
||||
assert(pair->dest_fd == STDOUT_FILENO);
|
||||
|
||||
const int fail = fcntl(STDOUT_FILENO, F_SETFL, stdout_flags);
|
||||
stdout_flags = 0;
|
||||
restore_stdout_flags = false;
|
||||
|
||||
if (fail) {
|
||||
if (fcntl(STDOUT_FILENO, F_SETFL, stdout_flags) == -1) {
|
||||
message_error(_("Error restoring the O_APPEND flag "
|
||||
"to standard output: %s"),
|
||||
strerror(errno));
|
||||
@@ -880,12 +1015,30 @@ io_read(file_pair *pair, io_buf *buf_union, size_t size)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
const io_wait_ret ret = io_wait(pair,
|
||||
mytime_get_flush_timeout(),
|
||||
true);
|
||||
switch (ret) {
|
||||
case IO_WAIT_MORE:
|
||||
continue;
|
||||
|
||||
case IO_WAIT_ERROR:
|
||||
return SIZE_MAX;
|
||||
|
||||
case IO_WAIT_TIMEOUT:
|
||||
return size - left;
|
||||
|
||||
default:
|
||||
message_bug();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
message_error(_("%s: Read error: %s"),
|
||||
pair->src_name, strerror(errno));
|
||||
|
||||
// FIXME Is this needed?
|
||||
pair->src_eof = true;
|
||||
|
||||
return SIZE_MAX;
|
||||
}
|
||||
|
||||
@@ -945,11 +1098,20 @@ io_write_buf(file_pair *pair, const uint8_t *buf, size_t size)
|
||||
if (amount == -1) {
|
||||
if (errno == EINTR) {
|
||||
if (user_abort)
|
||||
return -1;
|
||||
return true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
if (io_wait(pair, -1, false) == IO_WAIT_MORE)
|
||||
continue;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle broken pipe specially. gzip and bzip2
|
||||
// don't print anything on SIGPIPE. In addition,
|
||||
// gzip --quiet uses exit status 2 (warning) on
|
||||
|
||||
@@ -68,6 +68,14 @@ typedef struct {
|
||||
extern void io_init(void);
|
||||
|
||||
|
||||
#ifndef TUKLIB_DOSLIKE
|
||||
/// \brief Write a byte to user_abort_pipe[1]
|
||||
///
|
||||
/// This is called from a signal handler.
|
||||
extern void io_write_to_user_abort_pipe(void);
|
||||
#endif
|
||||
|
||||
|
||||
/// \brief Disable creation of sparse files when decompressing
|
||||
extern void io_no_sparse(void);
|
||||
|
||||
|
||||
@@ -230,6 +230,20 @@ parse_indexes(xz_file_info *xfi, file_pair *pair)
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Check that the Stream Footer doesn't specify something
|
||||
// that we don't support. This can only happen if the xz
|
||||
// version is older than liblzma and liblzma supports
|
||||
// something new.
|
||||
//
|
||||
// It is enough to check Stream Footer. Stream Header must
|
||||
// match when it is compared against Stream Footer with
|
||||
// lzma_stream_flags_compare().
|
||||
if (footer_flags.version != 0) {
|
||||
message_error("%s: %s", pair->src_name,
|
||||
message_strm(LZMA_OPTIONS_ERROR));
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Check that the size of the Index field looks sane.
|
||||
lzma_vli index_size = footer_flags.backward_size;
|
||||
if ((lzma_vli)(pos) < index_size + LZMA_STREAM_HEADER_SIZE) {
|
||||
@@ -456,7 +470,19 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter,
|
||||
switch (lzma_block_compressed_size(&block,
|
||||
iter->block.unpadded_size)) {
|
||||
case LZMA_OK:
|
||||
break;
|
||||
// Validate also block.uncompressed_size if it is present.
|
||||
// If it isn't present, there's no need to set it since
|
||||
// we aren't going to actually decompress the Block; if
|
||||
// we were decompressing, then we should set it so that
|
||||
// the Block decoder could validate the Uncompressed Size
|
||||
// that was stored in the Index.
|
||||
if (block.uncompressed_size == LZMA_VLI_UNKNOWN
|
||||
|| block.uncompressed_size
|
||||
== iter->block.uncompressed_size)
|
||||
break;
|
||||
|
||||
// If the above fails, the file is corrupt so
|
||||
// LZMA_DATA_ERROR is a good error code.
|
||||
|
||||
case LZMA_DATA_ERROR:
|
||||
// Free the memory allocated by lzma_block_header_decode().
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user