forked from scummvm/scummvm-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
example_tool.cpp
184 lines (143 loc) · 6.27 KB
/
example_tool.cpp
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* ScummVM Tools
*
* ScummVM Tools is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* Example of a compression tool for helping future (and current) coders.
* We require compression.h for the basic functions and utility classes
*/
#include "tool.h"
// Some files we need...
#include <sstream>
// We inherit from Tool, for compression tools, use the 'CompressionTool'
// Normally this declaration would be in the .h file
class CompressionExample : public Tool {
public:
// We pretty much always need a constructor
// It should not require any arguments passed
// We have a default value for name
CompressionExample(const std::string &name = "compress_example");
// Members should allows be public if they are set by command line parameters
// Since they need to be modified by the GUI / or other external applications
// that use us without having to construct a command line.
bool _outputFiles;
// We overload execute, which contains the actual code of the tool
virtual void execute();
protected:
void parseExtraArguments();
};
/* Implementation of the contsructor
* We pass the name and type of this tool to the base class
* Since the name changes if we are run in standalone mode, we pass it along
*/
CompressionExample::CompressionExample(const std::string &name) : Tool(name, TOOLTYPE_EXTRACTION) {
// Initialize our own
_outputFiles = false;
// If we don't support all formats, we only specify a few here (support for all formats is default)
// This makes no sense for an extraction tool, only for to make an example
_supportedFormats = AUDIO_MP3;
// Should be true if we can display progress in an incremental fashion, if we don't progress will be indeterminate
// We can show progress, so set it to true!
_supportsProgressBar = true;
// Here, we specify input files we accept
// Note that all input files specified here are _mandatory_ as inputs, and are parsed in order
// We don't actually need to parse these inputs ourselves, they are filled in automatically by the interface
ToolInput input1;
input1.format = "*.tx1";
input1.description = "The first input example file.";
_inputPaths.push_back(input1);
ToolInput input2;
input2.format = "*.tx2";
input2.description = "The second input example file.";
_inputPaths.push_back(input2);
// If we output to a directory, we should specify it explicitly
_outputToDirectory = true;
// Text displayed to the user for help when running as CLI
// Note that this includes our own name
_helptext = "Usage: " + _name + " [compression params] [-o <outputdir>] [-a] <input.ex1> <input.ex2>\n" +
"Specify -a to produce actual output files (otherwise it's just simulation)\n";
}
void CompressionExample::parseExtraArguments() {
// Here, we parse our own arguments
// Arguments are stored in the _arguments member.
// Remove any arguments that you have "used up"
if (!_arguments.empty() && _arguments.front() == "-a") {
// Set our member
_outputFiles = true;
// We matched one argument, so remove it
_arguments.pop_front();
}
}
void CompressionExample::execute() {
// By now, all arguments have been parsed, all members setup and all input paths setup
// If this was a compression tool _format would contain the selected audio format
// Note that we almost need no error handling, since exceptions will be thrown if we do
// something bad, and all parameters have already been setup
// This 'tool' doesn't takes two input files
// It writes the of each file 100 times into X files, where X is the input file size.
// _inputPaths[0].path is always valid and contains the correct path, same for 1
Common::Filename inpath1(_inputPaths[0].path);
Common::Filename inpath2(_inputPaths[1].path);
// We always need to setup default output path, since there is no obligation to specify it
// If you don't do this, the OS will usually default to the working directory, if we output a file
// it will fail most likely
if (_outputPath.empty())
_outputPath = "output/";
// The File class is very similar to the FILE struct, look in util.h for details
File in1(inpath1, "r");
File in2(inpath2, "r");
// Read the complete contents of the files (if they don't contain NUL ofcourse)
std::string text1 = in1.readString();
std::string text2 = in2.readString();
// Start the 'extraction'
size_t total_files = in1.size() + in2.size();
// There has to be some roof on this
if (total_files > 1000)
throw ToolException("Input files are too large!");
for (size_t i = 0; i < total_files; ++i) {
// This updates any progress bar, if there is any
// if you don't support progress bars, you should use notifyProgress instead
// to make sure progress can be aborted (print calls notifyProgress internally)
updateProgress(i, total_files);
// Convert i to string
std::ostringstream outname;
outname << i;
// Open a file for writing
if (_outputFiles) {
File out(_outputPath.getPath() + outname.str() + ".exo", "w");
// What we actually do, output some text a lot
for (size_t j = 0; j < 100; ++j) {
if (i < in1.size())
out.write(text1.c_str(), 1, text1.size());
else
out.write(text2.c_str(), 1, text2.size());
}
} else {
// Do nothing for awhile
for (int i = 0; i < 1000000; ++i) {
int *n = new int;
delete n;
}
}
// Print can also throw an AbortException
// Do NOT use printf or anything else that outputs to standard output, as it will not display in the GUI.
print("Outputted file %d of %d", i, total_files);
}
// We indicate success by not throwing any exceptions during the execution
print("Extraction finished without errors!");
}