1 | #include <port/unistd.h> |
2 | #include <zstd.h> |
3 | #include <vector> |
4 | #include <stdexcept> |
5 | #include <sys/types.h> |
6 | |
7 | |
8 | int main(int argc, char ** argv) |
9 | { |
10 | bool compress = argc == 1; |
11 | |
12 | const size_t size = 1048576; |
13 | std::vector<char> src_buf(size); |
14 | std::vector<char> dst_buf; |
15 | |
16 | size_t pos = 0; |
17 | while (true) |
18 | { |
19 | ssize_t read_res = read(STDIN_FILENO, &src_buf[pos], size - pos); |
20 | if (read_res < 0) |
21 | throw std::runtime_error("Cannot read from stdin" ); |
22 | if (read_res == 0) |
23 | break; |
24 | pos += read_res; |
25 | } |
26 | |
27 | src_buf.resize(pos); |
28 | |
29 | size_t zstd_res; |
30 | |
31 | if (compress) |
32 | { |
33 | dst_buf.resize(ZSTD_compressBound(src_buf.size())); |
34 | |
35 | zstd_res = ZSTD_compress( |
36 | &dst_buf[0], |
37 | dst_buf.size(), |
38 | &src_buf[0], |
39 | src_buf.size(), |
40 | 1); |
41 | } |
42 | else |
43 | { |
44 | dst_buf.resize(size); |
45 | |
46 | zstd_res = ZSTD_decompress( |
47 | &dst_buf[0], |
48 | dst_buf.size(), |
49 | &src_buf[0], |
50 | src_buf.size()); |
51 | } |
52 | |
53 | if (ZSTD_isError(zstd_res)) |
54 | throw std::runtime_error(ZSTD_getErrorName(zstd_res)); |
55 | |
56 | dst_buf.resize(zstd_res); |
57 | |
58 | pos = 0; |
59 | while (pos < dst_buf.size()) |
60 | { |
61 | ssize_t write_res = write(STDOUT_FILENO, &dst_buf[pos], dst_buf.size()); |
62 | if (write_res <= 0) |
63 | throw std::runtime_error("Cannot write to stdout" ); |
64 | pos += write_res; |
65 | } |
66 | |
67 | return 0; |
68 | } |
69 | |