separate resolving+scanning to own interface+class and avoid use of extern

This commit is contained in:
John
2023-05-18 12:24:50 +02:00
parent ec6dae6abb
commit e419c950d8
12 changed files with 860 additions and 640 deletions
+9 -7
View File
@@ -94,11 +94,6 @@ static const char* defaultMessageFieldMap[] = { // access level not included in
/** the m_pollOrder of the last polled message. */
static unsigned int g_lastPollOrder = 0;
extern DataFieldTemplates* getTemplates(const string& filename);
extern result_t loadDefinitionsFromConfigPath(FileReader* reader, const string& filename, bool verbose,
map<string, string>* defaults, string* errorDescription, bool replace = false);
Message::Message(const string& filename, const string& circuit, const string& level, const string& name,
bool isWrite, bool isPassive, const map<string, string>& attributes,
@@ -1738,7 +1733,11 @@ void Instruction::getDestination(ostringstream* ostream) const {
result_t LoadInstruction::execute(MessageMap* messages, ostringstream* log) {
string errorDescription;
result_t result = loadDefinitionsFromConfigPath(messages, m_filename, false, &m_defaults, &errorDescription);
Resolver* resolver = messages->getResolver();
if (!resolver) {
return RESULT_ERR_MISSING_ARG;
}
result_t result = resolver->loadDefinitionsFromConfigPath(messages, m_filename, &m_defaults, &errorDescription);
if (log->tellp() > 0) {
*log << ", ";
}
@@ -2306,7 +2305,10 @@ result_t MessageMap::addFromFile(const string& filename, unsigned int lineNo, ma
return RESULT_ERR_INVALID_ARG;
}
result = RESULT_ERR_EOF;
DataFieldTemplates* templates = getTemplates(filename);
if (!m_resolver) {
return result;
}
DataFieldTemplates* templates = m_resolver->getTemplates(filename);
bool hasMulti = types.find(VALUE_SEPARATOR) != string::npos;
istringstream stream(types);
string type;
+52 -1
View File
@@ -1255,6 +1255,43 @@ class LoadedFileInfo {
};
/**
* Interface for resolving templates and loading additional message definitions.
*/
class Resolver {
public:
/**
* Constructor.
*/
Resolver() {}
/**
* Destructor.
*/
virtual ~Resolver() {}
/**
* Get the @a DataFieldTemplates for the specified configuration file.
* @param filename the full name of the configuration file, or "*" to get the non-root templates with the longest name
* or the root templates if not available.
* @return the @a DataFieldTemplates.
*/
virtual DataFieldTemplates* getTemplates(const string& filename) = 0;
/**
* Load definitions from a relative file from the config path/URL.
* @param reader the @a FileReader instance to load with the definitions.
* @param filename the relative name of the file being read.
* @param defaults the default values by name (potentially overwritten by file name), or nullptr to not use defaults.
* @param errorDescription a string in which to store the error description in case of error.
* @param replace whether to replace an already existing entry.
* @return @a RESULT_OK on success, or an error code.
*/
virtual result_t loadDefinitionsFromConfigPath(FileReader* reader, const string& filename,
map<string, string>* defaults, string* errorDescription, bool replace = false) = 0;
};
/**
* Holds a map of all known @a Message instances.
*/
@@ -1267,7 +1304,7 @@ class MessageMap : public MappedFileReader {
* @param deleteData whether to delete the scan message @a DataField during @a Message destruction.
*/
explicit MessageMap(bool addAll = false, const string& preferLanguage = "", bool deleteData = true)
: MappedFileReader::MappedFileReader(true, preferLanguage),
: MappedFileReader::MappedFileReader(true, preferLanguage), m_resolver(nullptr),
m_addAll(addAll), m_additionalScanMessages(false), m_maxIdLength(0), m_maxBroadcastIdLength(0),
m_messageCount(0), m_conditionalMessageCount(0), m_passiveMessageCount(0) {
m_scanMessage = Message::createScanMessage(false, deleteData);
@@ -1289,6 +1326,17 @@ class MessageMap : public MappedFileReader {
}
}
/**
* Set the @a Resolver instance.
* @param the @a Resolver instance.
*/
void setResolver(Resolver* resolver) { m_resolver = resolver; }
/**
* @return the @a Resolver instance.
*/
Resolver* getResolver() const { return m_resolver; }
/**
* Add a @a Message instance to this set.
* @param message the @a Message instance to add.
@@ -1575,6 +1623,9 @@ class MessageMap : public MappedFileReader {
/** empty vector for @a getLoadedFiles(). */
static vector<string> s_noFiles;
/** the @a Resolver instance. */
Resolver* m_resolver;
/** whether to add all messages, even if duplicate. */
const bool m_addAll;
+20 -17
View File
@@ -54,27 +54,29 @@ DataFieldTemplates* templates = nullptr;
namespace ebusd {
DataFieldTemplates* getTemplates(const string& filename) {
if (filename == "") { // avoid compiler warning
class TestResolver : public Resolver {
public:
virtual DataFieldTemplates* getTemplates(const string& filename) {
if (filename == "") { // avoid compiler warning
return templates;
}
return templates;
}
return templates;
}
result_t loadDefinitionsFromConfigPath(FileReader* reader, const string& filename, bool verbose,
map<string, string>* defaults, string* errorDescription, bool replace = false) {
time_t mtime = 0;
istream* stream = FileReader::openFile(filename, errorDescription, &mtime);
result_t result;
if (stream) {
result = reader->readFromStream(stream, filename, mtime, verbose, defaults, errorDescription);
delete(stream);
} else {
result = RESULT_ERR_NOTFOUND;
virtual result_t loadDefinitionsFromConfigPath(FileReader* reader, const string& filename,
map<string, string>* defaults, string* errorDescription, bool replace = false) {
time_t mtime = 0;
istream* stream = FileReader::openFile(filename, errorDescription, &mtime);
result_t result;
if (stream) {
result = reader->readFromStream(stream, filename, mtime, false, defaults, errorDescription);
delete(stream);
} else {
result = RESULT_ERR_NOTFOUND;
}
return result;
}
return result;
}
};
} // namespace ebusd
@@ -208,6 +210,7 @@ int main() {
templates->readLineFromStream(&dummystr, __FILE__, false, &lineNo, &row, &errorDescription, false, nullptr, nullptr);
lineNo = 0;
MessageMap* messages = new MessageMap("");
messages->setResolver(new TestResolver());
dummystr.clear();
dummystr.str("#");
messages->readLineFromStream(&dummystr, __FILE__, false, &lineNo, &row, &errorDescription, false, nullptr, nullptr);