1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include "zstr.hpp"
void usage(std::ostream& os, const std::string& prog_name)
{
os << "Use: " << prog_name << " [-c] [-o output_file] files..." << std::endl
<< "Synposis:" << std::endl
<< " Decompress (with `-c`, compress) files to stdout (with `-o`, to output_file)." << std::endl;
}
void cat_stream(std::istream& is, std::ostream& os)
{
const std::streamsize buff_size = 1 << 16;
char * buff = new char [buff_size];
while (true)
{
is.read(buff, buff_size);
std::streamsize cnt = is.gcount();
if (cnt == 0) break;
os.write(buff, cnt);
}
delete [] buff;
} // cat_stream
void decompress_files(const std::vector< std::string >& file_v, const std::string& output_file)
{
//
// Set up sink ostream
//
std::unique_ptr< std::ofstream > ofs_p;
std::ostream * os_p = &std::cout;
if (not output_file.empty())
{
ofs_p = std::unique_ptr< std::ofstream >(new strict_fstream::ofstream(output_file));
os_p = ofs_p.get();
}
//
// Process files
//
for (const auto& f : file_v)
{
//
// If `f` is a file, create a zstr::ifstream, else (it is stdin) create a zstr::istream wrapper
//
std::unique_ptr< std::istream > is_p =
(f != "-"
? std::unique_ptr< std::istream >(new zstr::ifstream(f))
: std::unique_ptr< std::istream >(new zstr::istream(std::cin)));
//
// Cat stream
//
cat_stream(*is_p, *os_p);
}
} // decompress_files
void compress_files(const std::vector< std::string >& file_v, const std::string& output_file)
{
//
// Set up compression sink ostream
//
std::unique_ptr< std::ostream > os_p =
(not output_file.empty()
? std::unique_ptr< std::ostream >(new zstr::ofstream(output_file))
: std::unique_ptr< std::ostream >(new zstr::ostream(std::cout)));
//
// Process files
//
for (const auto& f : file_v)
{
//
// If `f` is a file, create an ifstream, else read stdin
//
std::unique_ptr< std::ifstream > ifs_p;
std::istream * is_p = &std::cin;
if (f != "-")
{
ifs_p = std::unique_ptr< std::ifstream >(new strict_fstream::ifstream(f));
is_p = ifs_p.get();
}
//
// Cat stream
//
cat_stream(*is_p, *os_p);
}
} // compress_files
int main(int argc, char * argv[])
{
bool compress = false;
std::string output_file;
int c;
while ((c = getopt(argc, argv, "co:h?")) != -1)
{
switch (c)
{
case 'c':
compress = true;
break;
case 'o':
if (std::string("-") != optarg)
{
output_file = optarg;
}
break;
case '?':
case 'h':
usage(std::cout, argv[0]);
std::exit(EXIT_SUCCESS);
break;
default:
usage(std::cerr, argv[0]);
std::exit(EXIT_FAILURE);
}
}
//
// Gather files to process
//
std::vector< std::string > file_v(&argv[optind], &argv[argc]);
//
// With no other arguments, process stdin
//
if (file_v.empty()) file_v.push_back("-");
//
// Perform compression/decompression
//
if (compress)
{
compress_files(file_v, output_file);
}
else
{
decompress_files(file_v, output_file);
}
}
|