📄 executor.cpp
字号:
//-------------------------------------------------------------------
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Revisions.....:
//===================================================================
#include <stdafx.h> // Precompiled headers.
#include <copyright.h>
#include <kernel/algorithms/executor.h>
#include <kernel/algorithms/keyword.h>
#include <kernel/utilities/iokit.h>
#include <kernel/utilities/systemkit.h>
#include <kernel/system/fstream.h>
#include <common/objectmanager.h>
//-------------------------------------------------------------------
// Methods for class Executor.
//===================================================================
//-------------------------------------------------------------------
// Constructors/destructor.
//===================================================================
Executor::Executor() {
SetOutputType(Undefined::Id());
SetCommandFilename(Undefined::String());
SetLogFilename(Undefined::String());
}
Executor::~Executor() {
}
//-------------------------------------------------------------------
// Methods inherited from Identifier.
//===================================================================
IMPLEMENTIDMETHODS(Executor, EXECUTOR, Algorithm)
//-------------------------------------------------------------------
// Methods inherited from Algorithm.
//===================================================================
//-------------------------------------------------------------------
// Method........: GetParameters
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
String
Executor::GetParameters() const {
String parameters;
// Output type.
parameters += Keyword::Output();
parameters += Keyword::Assignment();
parameters += IdHolder::GetClassname(GetOutputType());
parameters += Keyword::Separator();
// Filename (commands).
parameters += Keyword::Filename() + Keyword::Dot() + Keyword::Commands();
parameters += Keyword::Assignment();
parameters += GetCommandFilename();
parameters += Keyword::Separator();
// Filename (log).
parameters += Keyword::Filename() + Keyword::Dot() + Keyword::Log();
parameters += Keyword::Assignment();
parameters += GetLogFilename();
return parameters;
}
//-------------------------------------------------------------------
// Method........: GetOutputFilenames
// Author........: Aleksander 豩rn
// Date..........:
// Description...: See Algorithm::GetOutputFilenames method.
// Comments......:
// Revisions.....:
//===================================================================
bool
Executor::GetOutputFilenames(Vector(String) &filenames) const {
if (!Algorithm::GetOutputFilenames(filenames))
return false;
filenames.push_back(GetLogFilename());
return true;
}
//-------------------------------------------------------------------
// Method........: SetParameter
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
Executor::SetParameter(const String &keyword, const String &value) {
// Output type.
if (keyword == Keyword::Output())
return SetOutputType(IdHolder::GetId(value));
// Filename (commands).
if (keyword == Keyword::Filename() + Keyword::Dot() + Keyword::Commands())
return SetCommandFilename(value);
// Filename (commands). Backwards compatibility.
if (keyword == Keyword::Commands())
return SetCommandFilename(value);
// Filename (log).
if (keyword == Keyword::Filename() + Keyword::Dot() + Keyword::Log())
return SetLogFilename(value);
// Filename (log). Backwards compatibility.
if (keyword == Keyword::Log())
return SetLogFilename(value);
return Algorithm::SetParameter(keyword, value);
}
//-------------------------------------------------------------------
// Method........: IsApplicable
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
bool
Executor::IsApplicable(const Structure &structure, bool /*warn*/) const {
return structure.IsA(STRUCTURE);
}
//-------------------------------------------------------------------
// Method........: Apply
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......:
// Revisions.....:
//===================================================================
Structure *
Executor::Apply(Structure &structure) const {
// Check applicability.
if (!IsApplicable(structure))
return NULL;
// Command representation.
Algorithm::Handles algorithms;
Vector(String) parameters;
// Load commands.
if (!LoadCommands(GetCommandFilename(), algorithms, parameters)) {
Message::Error("Error reading commands from " + GetCommandFilename() + ".");
return NULL;
}
// Verify that the command set is not empty.
if (algorithms.empty()) {
Message::Error("No commands read from " + GetCommandFilename() + ".");
return NULL;
}
// Execute commands.
return ExecuteCommands(structure, algorithms, parameters);
}
//-------------------------------------------------------------------
// New (virtual) methods.
//===================================================================
//-------------------------------------------------------------------
// Method........: LoadCommands
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Returns (in-place) the commands (algorithms) and
// their parameters.
// Comments......:
// Revisions.....:
//===================================================================
bool
Executor::LoadCommands(const String &filename, Algorithm::Handles &algorithms, Vector(String) ¶meters) const {
ifstream stream;
if (!IOKit::Open(stream, filename)) {
Message::Error("Failed to open " + filename + ".");
return false;
}
// Clear inputs (in-place outputs).
algorithms.erase(algorithms.begin(), algorithms.end());
parameters.erase(parameters.begin(), parameters.end());
String line; // The line we read.
int line_no = 0; // The current line number in the file.
bool is_command = true; // Flag indicating how to interpret the line.
// Read all lines.
while (IOKit::LoadLine(stream, line, &line_no)) {
// Interpret line as a command or a parameter?
if (is_command) {
Id id = IdHolder::GetId(line);
if (id == Undefined::Id()) {
Message::Error("Unknown algorithm (" + line + ") on line " + String::Format(line_no) + ".");
return false;
}
Handle<Algorithm> algorithm = ObjectManager::GetIdentifiedAlgorithm(id);
if (algorithm == NULL) {
Message::Error("Algorithm " + line + " on line " + String::Format(line_no) + " not installed.");
return false;
}
algorithms.push_back(algorithm);
}
else {
line.Trim('{');
line.Trim('}');
parameters.push_back(line);
}
// Flip flag.
is_command = !is_command;
}
return true;
}
//-------------------------------------------------------------------
// Method........: ExecuteCommands
// Author........: Aleksander 豩rn
// Date..........:
// Description...: Opens log file and calls ExecuteCommands.
// Comments......:
// Revisions.....:
//===================================================================
Structure *
Executor::ExecuteCommands(Structure &structure, const Algorithm::Handles &algorithms, const Vector(String) ¶meters) const {
ofstream stream;
if (!IOKit::Open(stream, GetLogFilename())) {
Message::Error("Failed to open " + GetLogFilename() + " for output.");
return NULL;
}
// Save log header.
if (!SaveLogHeader(stream)) {
Message::Error("Failed to save log file header.");
return NULL;
}
// Execute commands.
Handle<Structure> output = ExecuteCommands(structure, algorithms, parameters, stream);
IOKit::Close(stream);
return output.Release();
}
//-------------------------------------------------------------------
// Method........: SaveLogHeader
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Called before execution.
// Revisions.....:
//===================================================================
bool
Executor::SaveLogHeader(ofstream &stream) const {
stream << "% Output from ROSETTA, " << SystemKit::GetUser() << " " << SystemKit::GetTimestamp() << endl;
stream << "%" << endl;
stream << "% " << IdHolder::GetClassname(GetId()) << endl;
stream << "% {" << GetParameters() << "}" << endl << endl;
return true;
}
//-------------------------------------------------------------------
// Method........: SaveLogEntry
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Called before execution step.
// Revisions.....:
//===================================================================
bool
Executor::SaveLogEntry(ofstream &stream, const Algorithm &algorithm) const {
String timestamp = SystemKit::GetTimestamp();
String indent(' ', timestamp.GetLength());
stream << timestamp << " Executing " << IdHolder::GetClassname(algorithm.GetId()) << "..." << endl;
stream << indent << " Parameters = {" << algorithm.GetParameters() << "}" << endl;
return true;
}
//-------------------------------------------------------------------
// Method........: SaveLogEntry
// Author........: Aleksander 豩rn
// Date..........:
// Description...:
// Comments......: Called after execution step.
// Revisions.....:
//===================================================================
bool
Executor::SaveLogEntry(ofstream &stream, const Structure &structure) const {
String timestamp = SystemKit::GetTimestamp();
String indent(' ', timestamp.GetLength());
stream << timestamp << " Output = " << IdHolder::GetClassname(structure.GetId()) << endl;
if (structure.HasMembers())
stream << indent << " #Members = " << structure.GetNoStructures() << endl;
if (structure.HasChildren())
stream << indent << " #Children = " << structure.GetNoChildren() << endl;
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -