Contents of /trunk/mkinitrd-magellan/busybox/archival/libunarchive/decompress_unxz.c
Parent Directory | Revision Log
Revision 1123 -
(show annotations)
(download)
Wed Aug 18 21:56:57 2010 UTC (13 years, 8 months ago) by niro
File MIME type: text/plain
File size: 2846 byte(s)
Wed Aug 18 21:56:57 2010 UTC (13 years, 8 months ago) by niro
File MIME type: text/plain
File size: 2846 byte(s)
-updated to busybox-1.17.1
1 | /* |
2 | * This file uses XZ Embedded library code which is written |
3 | * by Lasse Collin <lasse.collin@tukaani.org> |
4 | * and Igor Pavlov <http://7-zip.org/> |
5 | * |
6 | * See README file in unxz/ directory for more information. |
7 | * |
8 | * This file is: |
9 | * Copyright (C) 2010 Denys Vlasenko <vda.linux@googlemail.com> |
10 | * Licensed under GPLv2, see file LICENSE in this tarball for details. |
11 | */ |
12 | #include "libbb.h" |
13 | #include "unarchive.h" |
14 | |
15 | #define XZ_FUNC FAST_FUNC |
16 | #define XZ_EXTERN static |
17 | |
18 | #define XZ_DEC_DYNALLOC |
19 | |
20 | /* Skip check (rather than fail) of unsupported hash functions */ |
21 | #define XZ_DEC_ANY_CHECK 1 |
22 | |
23 | /* We use our own crc32 function */ |
24 | #define XZ_INTERNAL_CRC32 0 |
25 | static uint32_t *crc32_table; |
26 | static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) |
27 | { |
28 | crc = ~crc; |
29 | |
30 | while (size != 0) { |
31 | crc = crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8); |
32 | --size; |
33 | } |
34 | |
35 | return ~crc; |
36 | } |
37 | |
38 | /* We use arch-optimized unaligned accessors */ |
39 | #define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); }) |
40 | #define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); }) |
41 | #define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val)) |
42 | #define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val)) |
43 | |
44 | #include "unxz/xz_dec_bcj.c" |
45 | #include "unxz/xz_dec_lzma2.c" |
46 | #include "unxz/xz_dec_stream.c" |
47 | |
48 | IF_DESKTOP(long long) int FAST_FUNC |
49 | unpack_xz_stream(int src_fd, int dst_fd) |
50 | { |
51 | struct xz_buf iobuf; |
52 | struct xz_dec *state; |
53 | unsigned char *membuf; |
54 | IF_DESKTOP(long long) int total = 0; |
55 | |
56 | if (!crc32_table) |
57 | crc32_table = crc32_filltable(NULL, /*endian:*/ 0); |
58 | |
59 | memset(&iobuf, 0, sizeof(iobuf)); |
60 | /* Preload XZ file signature */ |
61 | membuf = (void*) strcpy(xmalloc(2 * BUFSIZ), HEADER_MAGIC); |
62 | iobuf.in = membuf; |
63 | iobuf.in_size = HEADER_MAGIC_SIZE; |
64 | iobuf.out = membuf + BUFSIZ; |
65 | iobuf.out_size = BUFSIZ; |
66 | |
67 | /* Limit memory usage to about 64 MiB. */ |
68 | state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024); |
69 | |
70 | while (1) { |
71 | enum xz_ret r; |
72 | |
73 | if (iobuf.in_pos == iobuf.in_size) { |
74 | int rd = safe_read(src_fd, membuf, BUFSIZ); |
75 | if (rd < 0) { |
76 | bb_error_msg(bb_msg_read_error); |
77 | total = -1; |
78 | break; |
79 | } |
80 | iobuf.in_size = rd; |
81 | iobuf.in_pos = 0; |
82 | } |
83 | // bb_error_msg(">in pos:%d size:%d out pos:%d size:%d", |
84 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size); |
85 | r = xz_dec_run(state, &iobuf); |
86 | // bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d", |
87 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r); |
88 | if (iobuf.out_pos) { |
89 | xwrite(dst_fd, iobuf.out, iobuf.out_pos); |
90 | IF_DESKTOP(total += iobuf.out_pos;) |
91 | iobuf.out_pos = 0; |
92 | } |
93 | if (r == XZ_STREAM_END) { |
94 | break; |
95 | } |
96 | if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) { |
97 | bb_error_msg("corrupted data"); |
98 | total = -1; |
99 | break; |
100 | } |
101 | } |
102 | xz_dec_end(state); |
103 | free(membuf); |
104 | |
105 | return total; |
106 | } |