1f0bd5302SXin LI /*
2f0bd5302SXin LI * Lazy test for the case when the output size is known
3f0bd5302SXin LI *
4f0bd5302SXin LI * Author: Lasse Collin <lasse.collin@tukaani.org>
5f0bd5302SXin LI *
6f0bd5302SXin LI * This file has been put into the public domain.
7f0bd5302SXin LI * You can do whatever you want with this file.
8f0bd5302SXin LI */
9f0bd5302SXin LI
10f0bd5302SXin LI #include <stdbool.h>
11f0bd5302SXin LI #include <stdio.h>
12f0bd5302SXin LI #include <string.h>
13f0bd5302SXin LI #include <stdlib.h>
14f0bd5302SXin LI #include "xz.h"
15f0bd5302SXin LI
16f0bd5302SXin LI static uint8_t in[1];
17f0bd5302SXin LI static uint8_t out[BUFSIZ];
18f0bd5302SXin LI
main(int argc,char ** argv)19f0bd5302SXin LI int main(int argc, char **argv)
20f0bd5302SXin LI {
21f0bd5302SXin LI struct xz_buf b;
22f0bd5302SXin LI struct xz_dec *s;
23f0bd5302SXin LI enum xz_ret ret;
24f0bd5302SXin LI const char *msg;
25f0bd5302SXin LI size_t uncomp_size;
26f0bd5302SXin LI
27f0bd5302SXin LI if (argc != 2) {
28*cd3a777bSXin LI fputs("Give uncompressed size as the argument\n", stderr);
29f0bd5302SXin LI return 1;
30f0bd5302SXin LI }
31f0bd5302SXin LI
32f0bd5302SXin LI uncomp_size = atoi(argv[1]);
33f0bd5302SXin LI
34f0bd5302SXin LI xz_crc32_init();
35f0bd5302SXin LI
36f0bd5302SXin LI /*
37f0bd5302SXin LI * Support up to 64 MiB dictionary. The actually needed memory
38f0bd5302SXin LI * is allocated once the headers have been parsed.
39f0bd5302SXin LI */
40f0bd5302SXin LI s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
41f0bd5302SXin LI if (s == NULL) {
42f0bd5302SXin LI msg = "Memory allocation failed\n";
43f0bd5302SXin LI goto error;
44f0bd5302SXin LI }
45f0bd5302SXin LI
46f0bd5302SXin LI b.in = in;
47f0bd5302SXin LI b.in_pos = 0;
48f0bd5302SXin LI b.in_size = 0;
49f0bd5302SXin LI b.out = out;
50f0bd5302SXin LI b.out_pos = 0;
51f0bd5302SXin LI b.out_size = uncomp_size < BUFSIZ ? uncomp_size : BUFSIZ;
52f0bd5302SXin LI
53f0bd5302SXin LI while (true) {
54f0bd5302SXin LI if (b.in_pos == b.in_size) {
55f0bd5302SXin LI b.in_size = fread(in, 1, sizeof(in), stdin);
56f0bd5302SXin LI b.in_pos = 0;
57f0bd5302SXin LI }
58f0bd5302SXin LI
59f0bd5302SXin LI ret = xz_dec_run(s, &b);
60f0bd5302SXin LI
61f0bd5302SXin LI if (b.out_pos == sizeof(out)) {
62f0bd5302SXin LI if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
63f0bd5302SXin LI msg = "Write error\n";
64f0bd5302SXin LI goto error;
65f0bd5302SXin LI }
66f0bd5302SXin LI
67f0bd5302SXin LI uncomp_size -= b.out_pos;
68f0bd5302SXin LI b.out_pos = 0;
69f0bd5302SXin LI b.out_size = uncomp_size < BUFSIZ
70f0bd5302SXin LI ? uncomp_size : BUFSIZ;
71f0bd5302SXin LI }
72f0bd5302SXin LI
73f0bd5302SXin LI if (ret == XZ_OK)
74f0bd5302SXin LI continue;
75f0bd5302SXin LI
76f0bd5302SXin LI #ifdef XZ_DEC_ANY_CHECK
77f0bd5302SXin LI if (ret == XZ_UNSUPPORTED_CHECK) {
78f0bd5302SXin LI fputs(argv[0], stderr);
79f0bd5302SXin LI fputs(": ", stderr);
80f0bd5302SXin LI fputs("Unsupported check; not verifying "
81f0bd5302SXin LI "file integrity\n", stderr);
82f0bd5302SXin LI continue;
83f0bd5302SXin LI }
84f0bd5302SXin LI #endif
85f0bd5302SXin LI
86f0bd5302SXin LI if (uncomp_size != b.out_pos) {
87f0bd5302SXin LI msg = "Uncompressed size doesn't match\n";
88f0bd5302SXin LI goto error;
89f0bd5302SXin LI }
90f0bd5302SXin LI
91f0bd5302SXin LI if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos
92f0bd5302SXin LI || fclose(stdout)) {
93f0bd5302SXin LI msg = "Write error\n";
94f0bd5302SXin LI goto error;
95f0bd5302SXin LI }
96f0bd5302SXin LI
97f0bd5302SXin LI switch (ret) {
98f0bd5302SXin LI case XZ_STREAM_END:
99f0bd5302SXin LI xz_dec_end(s);
100f0bd5302SXin LI return 0;
101f0bd5302SXin LI
102f0bd5302SXin LI case XZ_MEM_ERROR:
103f0bd5302SXin LI msg = "Memory allocation failed\n";
104f0bd5302SXin LI goto error;
105f0bd5302SXin LI
106f0bd5302SXin LI case XZ_MEMLIMIT_ERROR:
107f0bd5302SXin LI msg = "Memory usage limit reached\n";
108f0bd5302SXin LI goto error;
109f0bd5302SXin LI
110f0bd5302SXin LI case XZ_FORMAT_ERROR:
111f0bd5302SXin LI msg = "Not a .xz file\n";
112f0bd5302SXin LI goto error;
113f0bd5302SXin LI
114f0bd5302SXin LI case XZ_OPTIONS_ERROR:
115f0bd5302SXin LI msg = "Unsupported options in the .xz headers\n";
116f0bd5302SXin LI goto error;
117f0bd5302SXin LI
118f0bd5302SXin LI case XZ_DATA_ERROR:
119f0bd5302SXin LI case XZ_BUF_ERROR:
120f0bd5302SXin LI msg = "File is corrupt\n";
121f0bd5302SXin LI goto error;
122f0bd5302SXin LI
123f0bd5302SXin LI default:
124f0bd5302SXin LI msg = "Bug!\n";
125f0bd5302SXin LI goto error;
126f0bd5302SXin LI }
127f0bd5302SXin LI }
128f0bd5302SXin LI
129f0bd5302SXin LI error:
130f0bd5302SXin LI xz_dec_end(s);
131f0bd5302SXin LI fputs(argv[0], stderr);
132f0bd5302SXin LI fputs(": ", stderr);
133f0bd5302SXin LI fputs(msg, stderr);
134f0bd5302SXin LI return 1;
135f0bd5302SXin LI }
136