1
0
Fork 0
mirror of https://git.tukaani.org/xz.git synced 2024-04-04 12:36:23 +02:00

Oh well, big messy commit again. Some highlights:

- Updated to the latest, probably final file format version.
  - Command line tool reworked to not use threads anymore.
    Threading will probably go into liblzma anyway.
  - Memory usage limit is now about 30 % for uncompression
    and about 90 % for compression.
  - Progress indicator with --verbose
  - Simplified --help and full --long-help
  - Upgraded to the last LGPLv2.1+ getopt_long from gnulib.
  - Some bug fixes
This commit is contained in:
Lasse Collin 2008-11-19 20:46:52 +02:00
parent 3c3905b534
commit e114502b2b
112 changed files with 3255 additions and 2739 deletions

1
THANKS
View file

@ -16,6 +16,7 @@ In alphabetical order:
- Jim Meyering
- Igor Pavlov
- Mikko Pouru
- Bernhard Reutner-Fischer
- Alexandre Sauvé
- Andreas Schwab
- Julian Seward

View file

@ -54,7 +54,7 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [Enable debugging code.]),
if test "x$enable_debug" = xyes; then
AC_MSG_RESULT([yes])
else
AC_DEFINE(NDEBUG, 1, [Define to disable debugging code.])
AC_DEFINE(NDEBUG, 1, [Define to 1 to disable debugging code.])
AC_MSG_RESULT([no])
fi
@ -440,13 +440,34 @@ AC_CHECK_HEADERS([fcntl.h limits.h sys/time.h],
[AC_MSG_ERROR([Required header file(s) are missing.])])
# If any of these headers are missing, things should still work correctly:
AC_CHECK_HEADERS([assert.h errno.h byteswap.h sys/param.h sys/sysctl.h],
AC_CHECK_HEADERS([sys/param.h sys/sysctl.h byteswap.h],
[], [], [
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
])
# Even if we have byteswap.h, we may lack the specific macros/functions.
if test x$ac_cv_header_byteswap_h = xyes ; then
m4_foreach([FUNC], [bswap_16,bswap_32,bswap_64], [
AC_MSG_CHECKING([if FUNC is available])
AC_LINK_IFELSE([AC_LANG_SOURCE([
#include <byteswap.h>
int
main(void)
{
FUNC[](42);
return 0;
}
])], [
AC_DEFINE(HAVE_[]m4_toupper(FUNC), [1],
[Define to 1 if] FUNC [is available.])
AC_MSG_RESULT([yes])
], [AC_MSG_RESULT([no])])
])dnl
fi
###############################################################################
# Checks for typedefs, structures, and compiler characteristics.
@ -469,9 +490,13 @@ 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
# is used. Most systems seem to have st_xtim but BSDs have st_xtimespec.
AC_CHECK_MEMBERS([struct stat.st_atim.tv_nsec, struct stat.st_mtim.tv_nsec,
struct stat.st_atimespec.tv_nsec, struct stat.st_mtimespec.tv_nsec])
# is used.
AC_CHECK_MEMBERS([
struct stat.st_atim.tv_nsec,
struct stat.st_atimespec.tv_nsec,
struct stat.st_atimensec,
struct stat.st_uatime,
struct stat.st_atim.st__tim.tv_nsec])
AC_SYS_LARGEFILE
AC_C_BIGENDIAN
@ -484,16 +509,15 @@ AC_C_BIGENDIAN
# Gnulib replacements as needed
gl_GETOPT
# Functions that are not mandatory i.e. we have alternatives for them
# or we can just drop some functionality:
AC_CHECK_FUNCS([futimes futimesat])
# Find the best function to set timestamps.
AC_CHECK_FUNCS([futimens futimes futimesat utimes utime], [break])
# Check how to find out the amount of physical memory in the system. The
# lzma command line tool uses this to automatically limits its memory usage.
# - sysconf() gives all the needed info on GNU+Linux and Solaris.
# - BSDs use sysctl().
AC_MSG_CHECKING([how to detect the amount of physical memory])
AC_COMPILE_IFELSE([
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <unistd.h>
int
main()
@ -503,7 +527,7 @@ main()
i = sysconf(_SC_PHYS_PAGES);
return 0;
}
], [
]])], [
AC_DEFINE([HAVE_PHYSMEM_SYSCONF], 1,
[Define to 1 if the amount of physical memory can be detected
with sysconf(_SC_PAGESIZE) and sysconf(_SC_PHYS_PAGES).])
@ -537,7 +561,7 @@ main()
# sysconf(_SC_NPROCESSORS_ONLN) works on most systems, except that BSDs
# use sysctl().
AC_MSG_CHECKING([how to detect the number of available CPU cores])
AC_COMPILE_IFELSE([
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <unistd.h>
int
main()
@ -546,7 +570,7 @@ main()
i = sysconf(_SC_NPROCESSORS_ONLN);
return 0;
}
], [
]])], [
AC_DEFINE([HAVE_NCPU_SYSCONF], 1,
[Define to 1 if the number of available CPU cores can be
detected with sysconf(_SC_NPROCESSORS_ONLN).])

View file

@ -75,17 +75,17 @@ main(int argc, char **argv)
// Config
lzma_options_lzma opt_lzma;
if (lzma_lzma_preset(&opt_lzma, 0)) {
if (lzma_lzma_preset(&opt_lzma, 1)) {
fprintf(stderr, "preset failed\n");
exit(1);
}
lzma_filter filters[LZMA_BLOCK_FILTERS_MAX + 1];
lzma_filter filters[LZMA_FILTERS_MAX + 1];
filters[0].id = LZMA_FILTER_LZMA2;
filters[0].options = &opt_lzma;
filters[1].id = LZMA_VLI_UNKNOWN;
// Init
if (lzma_stream_encoder(&strm, filters, LZMA_CHECK_SHA256) != LZMA_OK) {
if (lzma_stream_encoder(&strm, filters, LZMA_CHECK_CRC32) != LZMA_OK) {
fprintf(stderr, "init failed\n");
exit(1);
}

View file

@ -48,7 +48,7 @@ main(void)
// Filter setup
lzma_options_lzma opt_lzma;
if (lzma_lzma_preset(&opt_lzma, 0))
if (lzma_lzma_preset(&opt_lzma, 1))
return 1;
lzma_filter filters[] = {

View file

@ -26,7 +26,7 @@ main(void)
lzma_init();
lzma_options_lzma lzma = {
.dict_size = (1U << 27) + (1U << 26),
.dict_size = (1U << 30) + (1U << 29),
.lc = 3,
.lp = 0,
.pb = 2,

View file

@ -87,7 +87,7 @@ main(int argc, char **argv)
};
lzma_options_delta opt_delta = {
.distance = 16
.dist = 16
};
lzma_options_subblock opt_subblock = {
@ -102,7 +102,7 @@ main(int argc, char **argv)
opt_subblock.subfilter_options.id = LZMA_FILTER_DELTA;
opt_subblock.subfilter_options.options = &opt_delta;
lzma_filter filters[LZMA_BLOCK_FILTERS_MAX + 1];
lzma_filter filters[LZMA_FILTERS_MAX + 1];
filters[0].id = LZMA_FILTER_LZMA2;
filters[0].options = &opt_lzma;
filters[1].id = LZMA_VLI_UNKNOWN;
@ -114,20 +114,20 @@ main(int argc, char **argv)
}
// Encoding
/*
encode(0, LZMA_SYNC_FLUSH);
encode(6, LZMA_SYNC_FLUSH);
encode(0, LZMA_SYNC_FLUSH);
encode(7, LZMA_SYNC_FLUSH);
encode(0, LZMA_SYNC_FLUSH);
encode(0, LZMA_FINISH);
*/
/*
encode(53, LZMA_SYNC_FLUSH);
// opt_lzma.literal_context_bits = 2;
// opt_lzma.literal_pos_bits = 1;
// opt_lzma.pos_bits = 0;
encode(404, LZMA_FINISH);
*/
// Clean up
lzma_end(&strm);

View file

@ -30,12 +30,13 @@ The .xz File Format
3.1.6. Header Padding
3.1.7. CRC32
3.2. Compressed Data
3.3. Check
3.3. Block Padding
3.4. Check
4. Index
4.1. Index Indicator
4.2. Number of Records
4.3. List of Records
4.3.1. Total Size
4.3.1. Unpadded Size
4.3.2. Uncompressed Size
4.4. Index Padding
4.5. CRC32
@ -56,7 +57,7 @@ The .xz File Format
0. Preface
This document describes the .xz file format (filename suffix
`.xz', MIME type `application/x-xz'). It is intended that this
".xz", MIME type "application/x-xz"). It is intended that this
this format replace the old .lzma format used by LZMA SDK and
LZMA Utils.
@ -80,12 +81,12 @@ The .xz File Format
Special thanks for helping with this document goes to
Igor Pavlov. Thanks for helping with this document goes to
Mark Adler, H. Peter Anvin, and Mikko Pouru.
Mark Adler, H. Peter Anvin, Mikko Pouru, and Lars Wirzenius.
0.2. Changes
Last modified: 2008-09-24 21:05+0300
Last modified: 2008-11-03 00:35+0200
(A changelog will be kept once the first official version
is made.)
@ -93,20 +94,19 @@ The .xz File Format
1. Conventions
The keywords `must', `must not', `required', `should',
`should not', `recommended', `may', and `optional' in this
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC-2119].
These words are not capitalized in this document.
Indicating a warning means displaying a message, returning
appropriate exit status, or something else to let the user
know that something worth warning occurred. The operation
should still finish if a warning is indicated.
appropriate exit status, or doing something else to let the
user know that something worth warning occurred. The operation
SHOULD still finish if a warning is indicated.
Indicating an error means displaying a message, returning
appropriate exit status, or something else to let the user
know that something prevented successfully finishing the
operation. The operation must be aborted once an error has
appropriate exit status, or doing something else to let the
user know that something prevented successfully finishing the
operation. The operation MUST be aborted once an error has
been indicated.
@ -114,7 +114,7 @@ The .xz File Format
In this document, byte is always 8 bits.
A `nul byte' has all bits unset. That is, the value of a nul
A "null byte" has all bits unset. That is, the value of a null
byte is 0x00.
To represent byte blocks, this document uses notation that
@ -133,8 +133,25 @@ The .xz File Format
+=======+
In this document, a boxed byte or a byte sequence declared
using this notation is called `a field'. The example field
above would be called `the Foo field' or plain `Foo'.
using this notation is called "a field". The example field
above would be called "the Foo field" or plain "Foo".
If there are many fields, they may be split to multiple lines.
This is indicated with an arrow ("--->"):
+=====+
| Foo |
+=====+
+=====+
---> | Bar |
+=====+
The above is equivalent to this:
+=====+=====+
| Foo | Bar |
+=====+=====+
1.2. Multibyte Integers
@ -166,7 +183,7 @@ The .xz File Format
size_t
encode(uint8_t buf[static 9], uint64_t num)
{
if (num >= UINT64_MAX / 2)
if (num > UINT64_MAX / 2)
return 0;
size_t i = 0;
@ -194,7 +211,7 @@ The .xz File Format
size_t i = 0;
while (buf[i++] & 0x80) {
if (i > size_max || buf[i] == 0x00)
if (i >= size_max || buf[i] == 0x00)
return 0;
*num |= (uint64_t)(buf[i] & 0x7F) << (i * 7);
@ -206,15 +223,22 @@ The .xz File Format
2. Overall Structure of .xz File
+========+================+========+================+
| Stream | Stream Padding | Stream | Stream Padding | ...
+========+================+========+================+
A standalone .xz files consist of one or more Streams which may
have Stream Padding between or after them:
A file contains usually only one Stream. However, it is
possible to concatenate multiple Streams together with no
additional processing. It is up to the implementation to
decide if the decoder will continue decoding from the next
Stream once the end of the first Stream has been reached.
+========+================+========+================+
| Stream | Stream Padding | Stream | Stream Padding | ...
+========+================+========+================+
While a typical file contains only one Stream and no Stream
Padding, a decoder handling standalone .xz files SHOULD support
files that have more than one Stream or Stream Padding.
In contrast to standalone .xz files, when the .xz file format
is used as an internal part of some other file format or
communication protocol, it usually is expected that the decoder
stops after the first Stream, and doesn't look for Stream
Padding or possibly other Streams.
2.1. Stream
@ -229,7 +253,7 @@ The .xz File Format
All the above fields have a size that is a multiple of four. If
Stream is used as an internal part of another file format, it
is recommended to make the Stream start at an offset that is
is RECOMMENDED to make the Stream start at an offset that is
a multiple of four bytes.
Stream Header, Index, and Stream Footer are always present in
@ -238,12 +262,12 @@ The .xz File Format
There are zero or more Blocks. The maximum number of Blocks is
limited only by the maximum size of the Index field.
Total size of a Stream must be less than 8 EiB (2^63 bytes).
Total size of a Stream MUST be less than 8 EiB (2^63 bytes).
The same limit applies to the total amount of uncompressed
data stored in a Stream.
If an implementation supports handling .xz files with multiple
concatenated Streams, it may apply the above limits to the file
concatenated Streams, it MAY apply the above limits to the file
as a whole instead of limiting per Stream basis.
@ -273,20 +297,20 @@ The .xz File Format
- The sixth byte (0x00) was chosen to prevent applications
from misdetecting the file as a text file.
If the Header Magic Bytes don't match, the decoder must
If the Header Magic Bytes don't match, the decoder MUST
indicate an error.
2.1.1.2. Stream Flags
The first byte of Stream Flags is always a nul byte. In future
The first byte of Stream Flags is always a null byte. In future
this byte may be used to indicate new Stream version or other
Stream properties.
The second byte of Stream Flags is a bit field:
Bit(s) Mask Description
0-3 0x0F Type of Check (see Section 3.3):
0-3 0x0F Type of Check (see Section 3.4):
ID Size Check name
0x00 0 bytes None
0x01 4 bytes CRC32
@ -304,14 +328,14 @@ The .xz File Format
0x0D 64 bytes (Reserved)
0x0E 64 bytes (Reserved)
0x0F 64 bytes (Reserved)
4-7 0xF0 Reserved for future use; must be zero for now.
4-7 0xF0 Reserved for future use; MUST be zero for now.
Implementations must support at least the Check IDs 0x00 (None)
and 0x01 (CRC32). Supporting other Check IDs is optional. If
an unsupported Check is used, the decoder should indicate a
warning or error.
Implementations SHOULD support at least the Check IDs 0x00
(None) and 0x01 (CRC32). Supporting other Check IDs is
OPTIONAL. If an unsupported Check is used, the decoder SHOULD
indicate a warning or error.
If any reserved bit is set, the decoder must indicate an error.
If any reserved bit is set, the decoder MUST indicate an error.
It is possible that there is a new field present which the
decoder is not aware of, and can thus parse the Stream Header
incorrectly.
@ -322,7 +346,7 @@ The .xz File Format
The CRC32 is calculated from the Stream Flags field. It is
stored as an unsigned 32-bit little endian integer. If the
calculated value does not match the stored one, the decoder
must indicate an error.
MUST indicate an error.
The idea is that Stream Flags would always be two bytes, even
if new features are needed. This way old decoders will be able
@ -344,7 +368,7 @@ The .xz File Format
The CRC32 is calculated from the Backward Size and Stream Flags
fields. It is stored as an unsigned 32-bit little endian
integer. If the calculated value does not match the stored one,
the decoder must indicate an error.
the decoder MUST indicate an error.
The reason to have the CRC32 field before the Backward Size and
Stream Flags fields is to keep the four-byte fields aligned to
@ -359,8 +383,11 @@ The .xz File Format
real_backward_size = (stored_backward_size + 1) * 4;
Using a fixed-size integer to store this value makes it
slightly simpler to parse the Stream Footer when the
If the stored value does not match the real size of the Index
field, the decoder MUST indicate an error.
Using a fixed-size integer to store Backward Size makes
it slightly simpler to parse the Stream Footer when the
application needs to parse the Stream backwards.
@ -368,16 +395,16 @@ The .xz File Format
This is a copy of the Stream Flags field from the Stream
Header. The information stored to Stream Flags is needed
when parsing the Stream backwards. The decoder must compare
when parsing the Stream backwards. The decoder MUST compare
the Stream Flags fields in both Stream Header and Stream
Footer, and indicate an error if they are not identical.
2.1.2.4. Footer Magic Bytes
As the last step of the decoding process, the decoder must
As the last step of the decoding process, the decoder MUST
verify the existence of Footer Magic Bytes. If they don't
match, an error must be indicated.
match, an error MUST be indicated.
Using a C array and ASCII:
const uint8_t FOOTER_MAGIC[2] = { 'Y', 'Z' };
@ -396,28 +423,28 @@ The .xz File Format
2.2. Stream Padding
Only the decoders that support decoding of concatenated Streams
must support Stream Padding.
MUST support Stream Padding.
Stream Padding must contain only nul bytes. Any non-nul byte
should be considered as the beginning of a new Stream. To
preserve the four-byte alignment of consecutive Streams, the
size of Stream Padding must be a multiple of four bytes. Empty
Stream Padding is allowed.
Stream Padding MUST contain only null bytes. To preserve the
four-byte alignment of consecutive Streams, the size of Stream
Padding MUST be a multiple of four bytes. Empty Stream Padding
is allowed.
Note that non-empty Stream Padding is allowed at the end of the
file; there doesn't need to be a new Stream after non-empty
Stream Padding. This can be convenient in certain situations
[GNU-tar].
The possibility of Padding should be taken into account when
designing an application that parses the Stream backwards.
The possibility of Padding MUST be taken into account when
designing an application that parses Streams backwards, and
the application supports concatenated Streams.
3. Block
+==============+=================+=======+
| Block Header | Compressed Data | Check |
+==============+=================+=======+
+==============+=================+===============+=======+
| Block Header | Compressed Data | Block Padding | Check |
+==============+=================+===============+=======+
3.1. Block Header
@ -460,11 +487,11 @@ The .xz File Format
Bit(s) Mask Description
0-1 0x03 Number of filters (1-4)
2-5 0x3C Reserved for future use; must be zero for now.
2-5 0x3C Reserved for future use; MUST be zero for now.
6 0x40 The Compressed Size field is present.
7 0x80 The Uncompressed Size field is present.
If any reserved bit is set, the decoder must indicate an error.
If any reserved bit is set, the decoder MUST indicate an error.
It is possible that there is a new field present which the
decoder is not aware of, and can thus parse the Block Header
incorrectly.
@ -475,14 +502,11 @@ The .xz File Format
This field is present only if the appropriate bit is set in
the Block Flags field (see Section 3.1.2).
This field contains the size of the Compressed Data field as
multiple of four bytes, minimum value being four bytes:
real_compressed_size = (stored_compressed_size + 1) * 4;
The size is stored using the encoding described in Section 1.2.
If the Compressed Size does not match the real size of the
Compressed Data field, the decoder must indicate an error.
The Compressed Size field contains the size of the Compressed
Data field, which MUST be non-zero. Compressed Size is stored
using the encoding described in Section 1.2. If the Compressed
Size doesn't match the size of the Compressed Data field, the
decoder MUST indicate an error.
3.1.4. Uncompressed Size
@ -493,7 +517,7 @@ The .xz File Format
The Uncompressed Size field contains the size of the Block
after uncompressing. Uncompressed Size is stored using the
encoding described in Section 1.2. If the Uncompressed Size
does not match the real uncompressed size, the decoder must
does not match the real uncompressed size, the decoder MUST
indicate an error.
Storing the Compressed Size and Uncompressed Size fields serves
@ -532,14 +556,14 @@ The .xz File Format
Filter IDs greater than or equal to 0x4000_0000_0000_0000
(2^62) are reserved for implementation-specific internal use.
These Filter IDs must never be used in List of Filter Flags.
These Filter IDs MUST never be used in List of Filter Flags.
3.1.6. Header Padding
This field contains as many nul byte as it is needed to make
This field contains as many null byte as it is needed to make
the Block Header have the size specified in Block Header Size.
If any of the bytes are not nul bytes, the decoder must
If any of the bytes are not null bytes, the decoder MUST
indicate an error. It is possible that there is a new field
present which the decoder is not aware of, and can thus parse
the Block Header incorrectly.
@ -550,7 +574,7 @@ The .xz File Format
The CRC32 is calculated over everything in the Block Header
field except the CRC32 field itself. It is stored as an
unsigned 32-bit little endian integer. If the calculated
value does not match the stored one, the decoder must indicate
value does not match the stored one, the decoder MUST indicate
an error.
By verifying the CRC32 of the Block Header before parsing the
@ -565,20 +589,23 @@ The .xz File Format
filters in Section 5.3, the format of the filter-specific
encoded data is out of scope of this document.
If the natural size of Compressed Data is not a multiple of
four bytes, it must be padded with 1-3 nul bytes to make it
a multiple of four bytes.
3.3. Block Padding
Block Padding MUST contain 0-3 null bytes to make the size of
the Block a multiple of four bytes. This can be needed when
the size of Compressed Data is not a multiple of four.
3.3. Check
3.4. Check
The type and size of the Check field depends on which bits
are set in the Stream Flags field (see Section 2.1.1.2).
The Check, when used, is calculated from the original
uncompressed data. If the calculated Check does not match the
stored one, the decoder must indicate an error. If the selected
type of Check is not supported by the decoder, it must indicate
stored one, the decoder MUST indicate an error. If the selected
type of Check is not supported by the decoder, it MUST indicate
a warning or error.
@ -611,7 +638,7 @@ The .xz File Format
Stream. The value is stored using the encoding described in
Section 1.2. If the decoder has decoded all the Blocks of the
Stream, and then notices that the Number of Records doesn't
match the real number of Blocks, the decoder must indicate an
match the real number of Blocks, the decoder MUST indicate an
error.
@ -624,39 +651,49 @@ The .xz File Format
| Record | Record | ...
+========+========+
Each Record contains two fields:
Each Record contains information about one Block:
+============+===================+
| Total Size | Uncompressed Size |
+============+===================+
+===============+===================+
| Unpadded Size | Uncompressed Size |
+===============+===================+
If the decoder has decoded all the Blocks of the Stream, it
must verify that the contents of the Records match the real
Total Size and Uncompressed Size of the respective Blocks.
MUST verify that the contents of the Records match the real
Unpadded Size and Uncompressed Size of the respective Blocks.
Implementation hint: It is possible to verify the Index with
constant memory usage by calculating for example SHA256 of both
the real size values and the List of Records, then comparing
the check values. Implementing this using non-cryptographic
check like CRC32 should be avoided unless small code size is
check like CRC32 SHOULD be avoided unless small code size is
important.
If the decoder supports random-access reading, it must verify
that Total Size and Uncompressed Size of every completely
If the decoder supports random-access reading, it MUST verify
that Unpadded Size and Uncompressed Size of every completely
decoded Block match the sizes stored in the Index. If only
partial Block is decoded, the decoder must verify that the
partial Block is decoded, the decoder MUST verify that the
processed sizes don't exceed the sizes stored in the Index.
4.3.1. Total Size
4.3.1. Unpadded Size
This field indicates the encoded size of the respective Block
as multiples of four bytes, minimum value being four bytes:
This field indicates the size of the Block excluding the Block
Padding field. That is, Unpadded Size is the size of the Block
Header, Compressed Data, and Check fields. Unpadded Size is
stored using the encoding described in Section 1.2. The value
MUST never be zero; with the current structure of Blocks, the
actual minimum value for Unpadded Size is five.
real_total_size = (stored_total_size + 1) * 4;
Implementation note: Because the size of the Block Padding
field is not included in Unpadded Size, calculating the total
size of a Stream or doing random-access reading requires
calculating the actual size of the Blocks by rounding Unpadded
Sizes up to the next multiple of four.
The value is stored using the encoding described in Section
1.2.
The reason to exclude Block Padding from Unpadded Size is to
ease making a raw copy of Compressed Data without Block
Padding. This can be useful, for example, if someone wants
to convert Streams to some other file format quickly.
4.3.2. Uncompressed Size
@ -668,7 +705,7 @@ The .xz File Format
4.4. Index Padding
This field must contain 0-3 nul bytes to pad the Index to
This field MUST contain 0-3 null bytes to pad the Index to
a multiple of four bytes.
@ -677,7 +714,7 @@ The .xz File Format
The CRC32 is calculated over everything in the Index field
except the CRC32 field itself. The CRC32 is stored as an
unsigned 32-bit little endian integer. If the calculated
value does not match the stored one, the decoder must indicate
value does not match the stored one, the decoder MUST indicate
an error.
@ -748,7 +785,7 @@ The .xz File Format
gets very little work done.
To prevent this kind of slow files, there are restrictions on
how the filters can be chained. These restrictions must be
how the filters can be chained. These restrictions MUST be
taken into account when designing new filters.
The maximum number of filters in the chain has been limited to
@ -756,11 +793,11 @@ The .xz File Format
Of these three non-last filters, only two are allowed to change
the size of the data.
The non-last filters, that change the size of the data, must
The non-last filters, that change the size of the data, MUST
have a limit how much the decoder can compress the data: the
decoder should produce at least n bytes of output when the
decoder SHOULD produce at least n bytes of output when the
filter is given 2n bytes of input. This limit is not
absolute, but significant deviations must be avoided.
absolute, but significant deviations MUST be avoided.
The above limitations guarantee that if the last filter in the
chain produces 4n bytes of output, the chain as a whole will
@ -797,7 +834,7 @@ The .xz File Format
Bits Mask Description
0-5 0x3F Dictionary Size
6-7 0xC0 Reserved for future use; must be zero for now.
6-7 0xC0 Reserved for future use; MUST be zero for now.
Dictionary Size is encoded with one-bit mantissa and five-bit
exponent. The smallest dictionary size is 4 KiB and the biggest
@ -847,11 +884,6 @@ The .xz File Format
Allow as a non-last filter: Yes
Allow as the last filter: No
Detecting when all of the data has been decoded:
Uncompressed size: Yes
End of Payload Marker: No
End of Input: Yes
Below is the list of filters in this category. The alignment
is the same for both input and output data.
@ -968,7 +1000,7 @@ The .xz File Format
There are several incompatible variations to calculate CRC32
and CRC64. For simplicity and clarity, complete examples are
provided to calculate the checks as they are used in this file
format. Implementations may use different code as long as it
format. Implementations MAY use different code as long as it
gives identical results.
The program below reads data from standard input, calculates
@ -1069,19 +1101,19 @@ The .xz File Format
[RFC-1952]
GZIP file format specification version 4.3
http://www.ietf.org/rfc/rfc1952.txt
- Notation of byte boxes in section `2.1. Overall conventions'
- Notation of byte boxes in section "2.1. Overall conventions"
[RFC-2119]
Key words for use in RFCs to Indicate Requirement Levels
http://www.ietf.org/rfc/rfc2119.txt
[GNU-tar]
GNU tar 1.16.1 manual
GNU tar 1.20 manual
http://www.gnu.org/software/tar/manual/html_node/Blocking-Factor.html
- Node 9.4.2 `Blocking Factor', paragraph that begins
`gzip will complain about trailing garbage'
- Node 9.4.2 "Blocking Factor", paragraph that begins
"gzip will complain about trailing garbage"
- Note that this URL points to the latest version of the
manual, and may some day not contain the note which is in
1.16.1. For the exact version of the manual, download GNU
tar 1.16.1: ftp://ftp.gnu.org/pub/gnu/tar/tar-1.16.1.tar.gz
1.20. For the exact version of the manual, download GNU
tar 1.20: ftp://ftp.gnu.org/pub/gnu/tar/tar-1.20.tar.gz

View file

@ -1,6 +1,5 @@
##
## Copyright (C) 2004-2007 Free Software Foundation, Inc.
## Copyright (C) 2007 Lasse Collin
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@ -13,7 +12,8 @@
## GNU General Public License for more details.
##
## Not using gnulib-tool, at least for now. Less mess this way.
## Not using gnulib-tool, at least for now. It is likely that we won't
## need anything else from Gnulib than getopt_long().
noinst_LIBRARIES = libgnu.a
@ -21,12 +21,12 @@ libgnu_a_SOURCES =
libgnu_a_DEPENDENCIES = $(LIBOBJS)
libgnu_a_LIBADD = $(LIBOBJS)
EXTRA_DIST = gettext.h getopt_.h getopt.c getopt1.c getopt_int.h
EXTRA_DIST = getopt.in.h getopt.c getopt1.c getopt_int.h
BUILT_SOURCES = $(GETOPT_H)
MOSTLYCLEANFILES = getopt.h getopt.h-t
getopt.h: getopt_.h
getopt.h: getopt.in.h
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
cat $(srcdir)/getopt_.h; \
cat $(srcdir)/getopt.in.h; \
} > $@-t
mv -f $@-t $@

View file

@ -7,16 +7,16 @@
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
@ -35,12 +35,18 @@
# include <unixlib.h>
#endif
/* Completely disable NLS for getopt. We won't include translations for it
anyway. If the system lacks getopt_long, missing translations probably
aren't a problem. */
/*
#ifdef _LIBC
# include <libintl.h>
#else
# include "gettext.h"
# define _(msgid) gettext (msgid)
#endif
*/
#define _(msgid) (msgid)
#if defined _LIBC && defined USE_IN_LIBIO
# include <wchar.h>

View file

@ -4,16 +4,16 @@
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

View file

@ -4,16 +4,16 @@
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License along
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */

View file

@ -1,240 +0,0 @@
/* Convenience header for conditional use of GNU <libintl.h>.
Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published
by the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA. */
#ifndef _LIBGETTEXT_H
#define _LIBGETTEXT_H 1
/* NLS can be disabled through the configure --disable-nls option.
*
* Extra hack in LZMA Utils: if DISABLE_NLS is defined, NLS is disabled
* even if ENABLE_NLS is true. See Makefile.am for more information.
*/
#if ENABLE_NLS && !defined(DISABLE_NLS)
/* Get declarations of GNU message catalog functions. */
# include <libintl.h>
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
the gettext() and ngettext() macros. This is an alternative to calling
textdomain(), and is useful for libraries. */
# ifdef DEFAULT_TEXT_DOMAIN
# undef gettext
# define gettext(Msgid) \
dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
# undef ngettext
# define ngettext(Msgid1, Msgid2, N) \
dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
# endif
#else
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
chokes if dcgettext is defined as a macro. So include it now, to make
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
as well because people using "gettext.h" will not include <libintl.h>,
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
is OK. */
#if defined(__sun)
# include <locale.h>
#endif
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# endif
#endif
/* Disabled NLS.
The casts to 'const char *' serve the purpose of producing warnings
for invalid uses of the value returned from these functions.
On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */
# define gettext(Msgid) ((const char *) (Msgid))
# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
# define dngettext(Domainname, Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
# define textdomain(Domainname) ((const char *) (Domainname))
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
#endif
/* A pseudo function call that serves as a marker for the automated
extraction of messages, but does not call gettext(). The run-time
translation is done at a different place in the code.
The argument, String, should be a literal string. Concatenated strings
and other string expressions won't work.
The macro's expansion is not parenthesized, so that it is suitable as
initializer for static 'char[]' or 'const char[]' variables. */
#define gettext_noop(String) String
/* The separator between msgctxt and msgid in a .mo file. */
#define GETTEXT_CONTEXT_GLUE "\004"
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
short and rarely need to change.
The letter 'p' stands for 'particular' or 'special'. */
#ifdef DEFAULT_TEXT_DOMAIN
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#else
# define pgettext(Msgctxt, Msgid) \
pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#endif
#define dpgettext(Domainname, Msgctxt, Msgid) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
#ifdef DEFAULT_TEXT_DOMAIN
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#else
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#endif
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
static inline const char *
pgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
int category)
{
const char *translation = dcgettext (domain, msg_ctxt_id, category);
if (translation == msg_ctxt_id)
return msgid;
else
return translation;
}
static inline const char *
npgettext_aux (const char *domain,
const char *msg_ctxt_id, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
const char *translation =
dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
if (translation == msg_ctxt_id || translation == msgid_plural)
return (n == 1 ? msgid : msgid_plural);
else
return translation;
}
/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
can be arbitrary expressions. But for string literals these macros are
less efficient than those above. */
#include <string.h>
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#endif
#define pgettext_expr(Msgctxt, Msgid) \
dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
static inline const char *
dcpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcgettext (domain, msg_ctxt_id, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (translation != msg_ctxt_id)
return translation;
}
return msgid;
}
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
static inline const char *
dcnpgettext_expr (const char *domain,
const char *msgctxt, const char *msgid,
const char *msgid_plural, unsigned long int n,
int category)
{
size_t msgctxt_len = strlen (msgctxt) + 1;
size_t msgid_len = strlen (msgid) + 1;
const char *translation;
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
char msg_ctxt_id[msgctxt_len + msgid_len];
#else
char buf[1024];
char *msg_ctxt_id =
(msgctxt_len + msgid_len <= sizeof (buf)
? buf
: (char *) malloc (msgctxt_len + msgid_len));
if (msg_ctxt_id != NULL)
#endif
{
memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
msg_ctxt_id[msgctxt_len - 1] = '\004';
memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
if (msg_ctxt_id != buf)
free (msg_ctxt_id);
#endif
if (!(translation == msg_ctxt_id || translation == msgid_plural))
return translation;
}
return (n == 1 ? msgid : msgid_plural);
}
#endif /* _LIBGETTEXT_H */

View file

@ -1,5 +1,5 @@
# getopt.m4 serial 13
dnl Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# getopt.m4 serial 14 (modified version)
dnl Copyright (C) 2002-2006, 2008 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@ -13,7 +13,6 @@ AC_DEFUN([gl_GETOPT_SUBSTITUTE],
AC_LIBOBJ([getopt])
AC_LIBOBJ([getopt1])
gl_GETOPT_SUBSTITUTE_HEADER
gl_PREREQ_GETOPT
])
AC_DEFUN([gl_GETOPT_SUBSTITUTE_HEADER],
@ -31,41 +30,32 @@ AC_DEFUN([gl_GETOPT_CHECK_HEADERS],
AC_CHECK_HEADERS([getopt.h], [], [GETOPT_H=getopt.h])
fi
dnl BSD getopt_long uses a way to reset option processing, that is different
dnl from GNU and Solaris (which copied the GNU behavior). We support both
dnl GNU and BSD style resetting of getopt_long(), so there's no need to use
dnl GNU getopt_long() on BSD due to different resetting style.
dnl
dnl With getopt_long(), some BSD versions have a bug in handling optional
dnl arguments. This bug appears only if the environment variable
dnl POSIXLY_CORRECT has been set, so it shouldn't be too bad in most
dnl cases; probably most don't have that variable set. But if we actually
dnl hit this bug, it is a real problem due to our heavy use of optional
dnl arguments.
dnl
dnl According to CVS logs, the bug was introduced in OpenBSD in 2003-09-22
dnl and copied to FreeBSD in 2004-02-24. It was fixed in both in 2006-09-22,
dnl so the affected versions shouldn't be popular anymore anyway. NetBSD
dnl never had this bug. TODO: What about Darwin and others?
if test -z "$GETOPT_H"; then
AC_CHECK_FUNCS([getopt_long_only], [], [GETOPT_H=getopt.h])
fi
dnl BSD getopt_long uses an incompatible method to reset option processing,
dnl and (as of 2004-10-15) mishandles optional option-arguments.
if test -z "$GETOPT_H"; then
AC_CHECK_DECL([optreset], [GETOPT_H=getopt.h], [], [#include <getopt.h>])
AC_CHECK_DECL([optreset],
[AC_DEFINE([HAVE_OPTRESET], 1,
[Define to 1 if getopt.h declares extern int optreset.])],
[], [#include <getopt.h>])
fi
dnl Solaris 10 getopt doesn't handle `+' as a leading character in an
dnl option string (as of 2005-05-05).
if test -z "$GETOPT_H"; then
AC_CACHE_CHECK([for working GNU getopt function], [gl_cv_func_gnu_getopt],
[AC_RUN_IFELSE(
[AC_LANG_PROGRAM([#include <getopt.h>],
[[
char *myargv[3];
myargv[0] = "conftest";
myargv[1] = "-+";
myargv[2] = 0;
return getopt (2, myargv, "+a") != '?';
]])],
[gl_cv_func_gnu_getopt=yes],
[gl_cv_func_gnu_getopt=no],
[dnl cross compiling - pessimistically guess based on decls
dnl Solaris 10 getopt doesn't handle `+' as a leading character in an
dnl option string (as of 2005-05-05).
AC_CHECK_DECL([getopt_clip],
[gl_cv_func_gnu_getopt=no], [gl_cv_func_gnu_getopt=yes],
[#include <getopt.h>])])])
if test "$gl_cv_func_gnu_getopt" = "no"; then
GETOPT_H=getopt.h
fi
fi
dnl option string (as of 2005-05-05). We don't use that feature, so this
dnl is not a problem for us. Thus, the respective test was removed here.
])
AC_DEFUN([gl_GETOPT_IFELSE],
@ -75,9 +65,3 @@ AC_DEFUN([gl_GETOPT_IFELSE],
])
AC_DEFUN([gl_GETOPT], [gl_GETOPT_IFELSE([gl_GETOPT_SUBSTITUTE])])
# Prerequisites of lib/getopt*.
AC_DEFUN([gl_PREREQ_GETOPT],
[
AC_CHECK_DECLS_ONCE([getenv])
])

View file

@ -16,20 +16,29 @@
// NOTE: We assume that config.h is already #included.
// byteswap.h is a GNU extension. It contains inline assembly versions
// for byteswapping. When byteswap.h is not available, we use generic code.
// At least glibc has byteswap.h which contains inline assembly code for
// byteswapping. Some systems have byteswap.h but lack one or more of the
// bswap_xx macros/functions, which is why we check them separately even
// if byteswap.h is available.
#ifdef HAVE_BYTESWAP_H
# include <byteswap.h>
#else
#endif
#ifndef HAVE_BSWAP_16
# define bswap_16(num) \
(((num) << 8) | ((num) >> 8))
#endif
#ifndef HAVE_BSWAP_32
# define bswap_32(num) \
( (((num) << 24) ) \
| (((num) << 8) & UINT32_C(0x00FF0000)) \
| (((num) >> 8) & UINT32_C(0x0000FF00)) \
| (((num) >> 24) ) )
#endif
#ifndef HAVE_BSWAP_64
# define bswap_64(num) \
( (((num) << 56) ) \
| (((num) << 40) & UINT64_C(0x00FF000000000000)) \

View file

@ -23,6 +23,10 @@
# endif
#endif
#if defined(HAVE_PHYSMEM_SYSCONF) || defined(HAVE_NCPU_SYSCONF)
# include <unistd.h>
#endif
/// \brief Get the amount of physical memory in bytes
///

View file

@ -111,6 +111,7 @@
#endif
#include <stdlib.h>
#include <assert.h>
// Pre-C99 systems lack stdbool.h. All the code in LZMA Utils must be written
// so that it works with fake bool type, for example:
@ -134,17 +135,6 @@ typedef unsigned char _Bool;
# define __bool_true_false_are_defined 1
#endif
#ifdef HAVE_ASSERT_H
# include <assert.h>
#else
# ifdef NDEBUG
# define assert(x)
# else
// TODO: Pretty bad assert macro.
# define assert(x) (!(x) && abort())
# endif
#endif
// string.h should be enough but let's include strings.h and memory.h too if
// they exists, since that shouldn't do any harm, but may improve portability.
#ifdef HAVE_STRING_H

View file

@ -1,6 +1,6 @@
/**
* \file lzma/block.h
* \brief .lzma Block handling
* \brief .xz Block handling
*
* \author Copyright (C) 1999-2006 Igor Pavlov
* \author Copyright (C) 2007 Lasse Collin
@ -131,11 +131,10 @@ typedef struct {
*
* \note Because of the array is terminated with
* .id = LZMA_VLI_UNKNOWN, the actual array must
* have LZMA_BLOCK_FILTERS_MAX + 1 members or the Block
* have LZMA_FILTERS_MAX + 1 members or the Block
* Header decoder will overflow the buffer.
*/
lzma_filter *filters;
# define LZMA_BLOCK_FILTERS_MAX 4
} lzma_block;
@ -148,6 +147,8 @@ typedef struct {
* The size can be calculated from the first byte of a Block using this macro.
* Note that if the first byte is 0x00, it indicates beginning of Index; use
* this macro only when the byte is not 0x00.
*
* There is no encoding macro, because Block Header encoder is enough for that.
*/
#define lzma_block_header_size_decode(b) (((uint32_t)(b) + 1) * 4)
@ -211,38 +212,50 @@ extern lzma_ret lzma_block_header_decode(lzma_block *options,
/**
* \brief Sets Compressed Size according to Total Size
* \brief Sets Compressed Size according to Unpadded Size
*
* Block Header stores Compressed Size, but Index has Total Size. If the
* Block Header stores Compressed Size, but Index has Unpadded Size. If the
* application has already parsed the Index and is now decoding Blocks,
* it can calculate Compressed Size from Total Size. This function does
* it can calculate Compressed Size from Unpadded Size. This function does
* exactly that with error checking, so application doesn't need to check,
* for example, if the value in Index is too small to contain even the
* Block Header. Note that you need to call this function after decoding
* Block Header. Note that you need to call this function _after_ decoding
* the Block Header field.
*
* \return - LZMA_OK: options->compressed_size was set successfully.
* - LZMA_DATA_ERROR: total_size is too small compared to
* - LZMA_DATA_ERROR: unpadded_size is too small compared to
* options->header_size and lzma_check_sizes[options->check].
* - LZMA_PROG_ERROR: Some values are invalid. For example,
* total_size and options->header_size must be multiples
* of four, total_size must be at least 12, and
* options->header_size must be a multiple of four, and
* options->header_size between 8 and 1024 inclusive.
*/
extern lzma_ret lzma_block_total_size_set(
lzma_block *options, lzma_vli total_size)
extern lzma_ret lzma_block_compressed_size(
lzma_block *options, lzma_vli unpadded_size)
lzma_attr_warn_unused_result;
/**
* \brief Calculates Total Size
* \brief Calculates Unpadded<