1#include <port/unistd.h>
2#include <zstd.h>
3#include <vector>
4#include <stdexcept>
5#include <sys/types.h>
6
7
8int 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