• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 26995937053

04 Jun 2026 09:38PM UTC coverage: 89.394% (-2.3%) from 91.672%
26995937053

push

github

web-flow
Merge pull request #5642 from randombit/jack/prefetch-in-ks

Improve prefetching for table based implementations

110588 of 123708 relevant lines covered (89.39%)

11056434.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.87
/src/cli/compress.cpp
1
/*
2
* (C) 2014,2015 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "cli.h"
8

9
#if defined(BOTAN_HAS_COMPRESSION)
10
   #include <botan/compression.h>
11
   #include <fstream>
12
#endif
13

14
namespace Botan_CLI {
15

16
namespace {
17

18
#if defined(BOTAN_HAS_COMPRESSION)
19

20
class Compress final : public Command {
21
   public:
22
      Compress() : Command("compress --type=gzip --level=6 --buf-size=8192 file") {}
4✔
23

24
      static std::string output_filename(const std::string& input_fsname, const std::string& comp_type) {
1✔
25
         const std::map<std::string, std::string> suffixes = {
1✔
26
            {"zlib", "zlib"},
27
            {"gzip", "gz"},
28
            {"bzip2", "bz2"},
29
            {"lzma", "xz"},
30
         };
5✔
31

32
         auto suffix_info = suffixes.find(comp_type);
1✔
33
         if(!suffixes.contains(comp_type)) {
1✔
34
            throw CLI_Error_Unsupported("Compressing", comp_type);
×
35
         }
36

37
         return input_fsname + "." + suffix_info->second;
2✔
38
      }
2✔
39

40
      std::string group() const override { return "compression"; }
1✔
41

42
      std::string description() const override { return "Compress a given file"; }
1✔
43

44
      void go() override {
1✔
45
         const std::string comp_type = get_arg("type");
1✔
46
         const size_t buf_size = get_arg_sz("buf-size");
1✔
47
         const size_t comp_level = get_arg_sz("level");
1✔
48

49
         auto compress = Botan::Compression_Algorithm::create(comp_type);
1✔
50
         if(!compress) {
1✔
51
            throw CLI_Error_Unsupported("Compression", comp_type);
×
52
         }
53

54
         const std::string in_file = get_arg("file");
1✔
55
         std::ifstream in(in_file, std::ios::binary);
1✔
56

57
         if(!in.good()) {
1✔
58
            throw CLI_IO_Error("reading", in_file);
×
59
         }
60

61
         const std::string out_file = output_filename(in_file, comp_type);
1✔
62
         std::ofstream out(out_file, std::ios::binary);
1✔
63
         if(!out.good()) {
1✔
64
            throw CLI_IO_Error("writing", out_file);
×
65
         }
66

67
         Botan::secure_vector<uint8_t> buf;
1✔
68

69
         compress->start(comp_level);
1✔
70

71
         while(in.good()) {
2✔
72
            buf.resize(buf_size);
1✔
73
            in.read(reinterpret_cast<char*>(buf.data()), buf.size());
1✔
74
            buf.resize(in.gcount());
1✔
75

76
            compress->update(buf);
1✔
77

78
            out.write(reinterpret_cast<const char*>(buf.data()), buf.size());
1✔
79
         }
80

81
         buf.clear();
1✔
82
         compress->finish(buf);
1✔
83
         out.write(reinterpret_cast<const char*>(buf.data()), buf.size());
1✔
84
         out.close();
1✔
85
      }
2✔
86
};
87

88
BOTAN_REGISTER_COMMAND("compress", Compress);
2✔
89

90
class Decompress final : public Command {
91
   public:
92
      Decompress() : Command("decompress --buf-size=8192 file") {}
4✔
93

94
      static void parse_extension(const std::string& in_file, std::string& out_file, std::string& suffix) {
1✔
95
         auto last_dot = in_file.find_last_of('.');
1✔
96
         if(last_dot == std::string::npos || last_dot == 0) {
1✔
97
            throw CLI_Error("No extension detected in filename '" + in_file + "'");
×
98
         }
99

100
         out_file = in_file.substr(0, last_dot);
1✔
101
         suffix = in_file.substr(last_dot + 1, std::string::npos);
1✔
102
      }
1✔
103

104
      std::string group() const override { return "compression"; }
1✔
105

106
      std::string description() const override { return "Decompress a given compressed archive"; }
1✔
107

108
      void go() override {
1✔
109
         const size_t buf_size = get_arg_sz("buf-size");
1✔
110
         const std::string in_file = get_arg("file");
1✔
111
         std::string out_file;
1✔
112
         std::string suffix;
1✔
113
         parse_extension(in_file, out_file, suffix);
1✔
114

115
         std::ifstream in(in_file, std::ios::binary);
1✔
116

117
         if(!in.good()) {
1✔
118
            throw CLI_IO_Error("reading", in_file);
×
119
         }
120

121
         auto decompress = Botan::Decompression_Algorithm::create(suffix);
1✔
122

123
         if(!decompress) {
1✔
124
            throw CLI_Error_Unsupported("Decompression", suffix);
×
125
         }
126

127
         std::ofstream out(out_file, std::ios::binary);
1✔
128
         if(!out.good()) {
1✔
129
            throw CLI_IO_Error("writing", out_file);
×
130
         }
131

132
         Botan::secure_vector<uint8_t> buf;
1✔
133

134
         decompress->start();
1✔
135

136
         while(in.good()) {
2✔
137
            buf.resize(buf_size);
1✔
138
            in.read(reinterpret_cast<char*>(buf.data()), buf.size());
1✔
139
            buf.resize(in.gcount());
1✔
140

141
            decompress->update(buf);
1✔
142

143
            out.write(reinterpret_cast<const char*>(buf.data()), buf.size());
1✔
144
         }
145

146
         buf.clear();
1✔
147
         decompress->finish(buf);
1✔
148
         out.write(reinterpret_cast<const char*>(buf.data()), buf.size());
1✔
149
         out.close();
1✔
150
      }
2✔
151
};
152

153
BOTAN_REGISTER_COMMAND("decompress", Decompress);
2✔
154

155
#endif
156

157
}  // namespace
158

159
}  // namespace Botan_CLI
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc