added support for retrieving configuration files from config service URL and changed that to be the default, always store loaded files by relative path, changed FileReader to allow reading from stream as well
This commit is contained in:
+23
-19
@@ -36,43 +36,47 @@ using std::setw;
|
||||
using std::dec;
|
||||
|
||||
|
||||
result_t FileReader::readFromFile(const string& filename, bool verbose, map<string, string>* defaults,
|
||||
string* errorDescription, size_t* hash, size_t* size, time_t* time) {
|
||||
istream* FileReader::openFile(const string& filename, string* errorDescription, time_t* time) {
|
||||
struct stat st;
|
||||
if (stat(filename.c_str(), &st) != 0) {
|
||||
*errorDescription = filename;
|
||||
return RESULT_ERR_NOTFOUND;
|
||||
return NULL;
|
||||
}
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
*errorDescription = filename+" is a directory";
|
||||
return RESULT_ERR_NOTFOUND;
|
||||
return NULL;
|
||||
}
|
||||
ifstream stream;
|
||||
stream.open(filename.c_str(), ifstream::in);
|
||||
if (!stream.is_open()) {
|
||||
ifstream* stream = new ifstream();
|
||||
stream->open(filename.c_str(), ifstream::in);
|
||||
if (!stream->is_open()) {
|
||||
*errorDescription = filename;
|
||||
return RESULT_ERR_NOTFOUND;
|
||||
delete(stream);
|
||||
return NULL;
|
||||
}
|
||||
if (time) {
|
||||
*time = st.st_mtime;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
result_t FileReader::readFromStream(istream* stream, const string& filename, time_t& mtime, bool verbose,
|
||||
map<string, string>* defaults, string* errorDescription, size_t* hash, size_t* size) {
|
||||
if (hash) {
|
||||
*hash = 0;
|
||||
}
|
||||
if (size) {
|
||||
*size = 0;
|
||||
}
|
||||
if (time) {
|
||||
*time = st.st_mtime;
|
||||
}
|
||||
unsigned int lineNo = 0;
|
||||
vector<string> row;
|
||||
result_t result = RESULT_OK;
|
||||
while (stream.peek() != EOF && result == RESULT_OK) {
|
||||
result = readLineFromStream(filename, verbose, &stream, &lineNo, &row, errorDescription, hash, size);
|
||||
while (stream->peek() != EOF && result == RESULT_OK) {
|
||||
result = readLineFromStream(stream, filename, verbose, &lineNo, &row, errorDescription, hash, size);
|
||||
}
|
||||
stream.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
result_t FileReader::readLineFromStream(const string& filename, bool verbose, istream* stream,
|
||||
result_t FileReader::readLineFromStream(istream* stream, const string& filename, bool verbose,
|
||||
unsigned int* lineNo, vector<string>* row, string* errorDescription, size_t* hash, size_t* size) {
|
||||
result_t result;
|
||||
if (!splitFields(stream, row, lineNo, hash, size)) {
|
||||
@@ -237,8 +241,8 @@ const string MappedFileReader::normalizeLanguage(const string& lang) {
|
||||
return normLang;
|
||||
}
|
||||
|
||||
result_t MappedFileReader::readFromFile(const string& filename, bool verbose, map<string, string>* defaults,
|
||||
string* errorDescription, size_t* hash, size_t* size, time_t* time) {
|
||||
result_t MappedFileReader::readFromStream(istream* stream, const string& filename, time_t& mtime, bool verbose,
|
||||
map<string, string>* defaults, string* errorDescription, size_t* hash, size_t* size) {
|
||||
m_mutex.lock();
|
||||
m_columnNames.clear();
|
||||
m_lastDefaults.clear();
|
||||
@@ -248,8 +252,8 @@ result_t MappedFileReader::readFromFile(const string& filename, bool verbose, ma
|
||||
}
|
||||
size_t lastSep = filename.find_last_of('/');
|
||||
string defaultsPart = lastSep == string::npos ? filename : filename.substr(lastSep+1);
|
||||
extractDefaultsFromFilename(defaultsPart, &m_lastDefaults[""], NULL, NULL, NULL);
|
||||
result_t result = FileReader::readFromFile(filename, verbose, defaults, errorDescription, hash, size, time);
|
||||
extractDefaultsFromFilename(defaultsPart, &m_lastDefaults[""]);
|
||||
result_t result = FileReader::readFromStream(stream, filename, mtime, verbose, defaults, errorDescription, hash, size);
|
||||
m_mutex.unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
+22
-12
@@ -76,24 +76,34 @@ class FileReader {
|
||||
virtual ~FileReader() {}
|
||||
|
||||
/**
|
||||
* Read the definitions from a file.
|
||||
* Open a file as stream for reading.
|
||||
* @param filename the name of the file being read.
|
||||
* @param errorDescription a string in which to store the error description in case of error.
|
||||
* @param time optional pointer to a @a time_t value for storing the modification time of the file, or NULL.
|
||||
* @return the opened @a istream on success, or NULL on error.
|
||||
*/
|
||||
static istream* openFile(const string& filename, string* errorDescription, time_t* time = NULL);
|
||||
|
||||
/**
|
||||
* Read the definitions from a stream.
|
||||
* @param stream the @a istream to read from.
|
||||
* @param filename the relative name of the file being read.
|
||||
* @param mtime a @a time_t value with the modification time of the file.
|
||||
* @param verbose whether to verbosely log problems.
|
||||
* @param defaults the default values by name (potentially overwritten by file name), or NULL to not use defaults.
|
||||
* @param errorDescription a string in which to store the error description in case of error.
|
||||
* @param hash optional pointer to a @a size_t value for storing the hash of the file, or NULL.
|
||||
* @param size optional pointer to a @a size_t value for storing the normalized size of the file, or NULL.
|
||||
* @param time optional pointer to a @a time_t value for storing the modification time of the file, or NULL.
|
||||
* @return @a RESULT_OK on success, or an error code.
|
||||
*/
|
||||
virtual result_t readFromFile(const string& filename, bool verbose, map<string, string>* defaults,
|
||||
string* errorDescription, size_t* hash, size_t* size, time_t* time);
|
||||
virtual result_t readFromStream(istream* stream, const string& filename, time_t& mtime, bool verbose,
|
||||
map<string, string>* defaults, string* errorDescription, size_t* hash = NULL, size_t* size = NULL);
|
||||
|
||||
/**
|
||||
* Read a single line definition from the stream.
|
||||
* @param stream the @a istream to read from.
|
||||
* @param filename the name of the file being read.
|
||||
* @param verbose whether to verbosely log problems.
|
||||
* @param stream the @a istream to read from.
|
||||
* @param lineNo the last line number (incremented with each line read).
|
||||
* @param row the definition row to clear and update with the read data (for performance reasons only).
|
||||
* @param errorDescription a string in which to store the error description in case of error.
|
||||
@@ -101,7 +111,7 @@ class FileReader {
|
||||
* @param size optional pointer to a @a size_t value for updating with the normalized length of the line, or NULL.
|
||||
* @return @a RESULT_OK on success, or an error code.
|
||||
*/
|
||||
virtual result_t readLineFromStream(const string& filename, bool verbose, istream* stream,
|
||||
virtual result_t readLineFromStream(istream* stream, const string& filename, bool verbose,
|
||||
unsigned int* lineNo, vector<string>* row, string* errorDescription, size_t* hash, size_t* size);
|
||||
|
||||
/**
|
||||
@@ -194,20 +204,20 @@ class MappedFileReader : public FileReader {
|
||||
static const string normalizeLanguage(const string& lang);
|
||||
|
||||
// @copydoc
|
||||
result_t readFromFile(const string& filename, bool verbose, map<string, string>* defaults,
|
||||
string* errorDescription, size_t* hash, size_t* size, time_t* time) override;
|
||||
result_t readFromStream(istream* stream, const string& filename, time_t& mtime, bool verbose,
|
||||
map<string, string>* defaults, string* errorDescription, size_t* hash = NULL, size_t* size = NULL) override;
|
||||
|
||||
/**
|
||||
* Extract default values from the file name.
|
||||
* @param filename the name of the file (without path)
|
||||
* @param defaults the default values by name to add to.
|
||||
* @param destAddress a pointer to a variable in which to store the numeric destination address, or NULL.
|
||||
* @param software a pointer to a in which to store the numeric software version, or NULL.
|
||||
* @param hardware a pointer to a in which to store the numeric hardware version, or NULL.
|
||||
* @param destAddress optional pointer to a variable in which to store the numeric destination address, or NULL.
|
||||
* @param software optional pointer to a in which to store the numeric software version, or NULL.
|
||||
* @param hardware optional pointer to a in which to store the numeric hardware version, or NULL.
|
||||
* @return true if the minimum parts were extracted, false otherwise.
|
||||
*/
|
||||
virtual bool extractDefaultsFromFilename(const string& filename, map<string, string>* defaults,
|
||||
symbol_t* destAddress, unsigned int* software, unsigned int* hardware) const {
|
||||
symbol_t* destAddress = NULL, unsigned int* software = NULL, unsigned int* hardware = NULL) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+12
-23
@@ -81,6 +81,9 @@ static const char* defaultMessageFieldMap[] = { // access level not included in
|
||||
|
||||
extern DataFieldTemplates* getTemplates(const string& filename);
|
||||
|
||||
extern result_t loadDefinitionsFromConfigPath(FileReader* reader, const string& filename, bool verbose,
|
||||
map<string, string>* defaults, string* errorDescription);
|
||||
|
||||
|
||||
Message::Message(const string& circuit, const string& level, const string& name,
|
||||
bool isWrite, bool isPassive, const map<string, string>& attributes,
|
||||
@@ -1692,10 +1695,9 @@ void Instruction::getDestination(ostringstream* ostream) const {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result_t LoadInstruction::execute(MessageMap* messages, ostringstream* log) {
|
||||
string errorDescription;
|
||||
result_t result = messages->readFromFile(m_filename, false, &m_defaults, &errorDescription, NULL, NULL, NULL);
|
||||
result_t result = loadDefinitionsFromConfigPath(messages, m_filename, false, &m_defaults, &errorDescription);
|
||||
if (log->tellp() > 0) {
|
||||
*log << ", ";
|
||||
}
|
||||
@@ -1731,13 +1733,6 @@ result_t LoadInstruction::execute(MessageMap* messages, ostringstream* log) {
|
||||
|
||||
vector<string> MessageMap::s_noFiles;
|
||||
|
||||
const string MessageMap::getRelativePath(const string& filename) const {
|
||||
if (filename.length() >= m_configPath.length() && filename.substr(0, m_configPath.length()) == m_configPath) {
|
||||
return filename.substr(m_configPath.length());
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
result_t MessageMap::add(bool storeByName, Message* message) {
|
||||
uint64_t key = message->getKey();
|
||||
bool conditional = message->isConditional();
|
||||
@@ -2109,20 +2104,16 @@ bool MessageMap::extractDefaultsFromFilename(const string& filename, map<string,
|
||||
return true;
|
||||
}
|
||||
|
||||
result_t MessageMap::readFromFile(const string& filename, bool verbose, map<string, string>* defaults,
|
||||
string* errorDescription, size_t* hash, size_t* size, time_t* time) {
|
||||
result_t MessageMap::readFromStream(istream* stream, const string& filename, time_t& mtime, bool verbose,
|
||||
map<string, string>* defaults, string* errorDescription, size_t* hash, size_t* size) {
|
||||
size_t localHash, localSize;
|
||||
time_t localTime;
|
||||
if (!hash) {
|
||||
hash = &localHash;
|
||||
}
|
||||
if (!size) {
|
||||
size = &localSize;
|
||||
}
|
||||
if (!time) {
|
||||
time = &localTime;
|
||||
}
|
||||
result_t result = MappedFileReader::readFromFile(filename, verbose, defaults, errorDescription, hash, size, time);
|
||||
result_t result = MappedFileReader::readFromStream(stream, filename, mtime, verbose, defaults, errorDescription, hash, size);
|
||||
if (defaults) {
|
||||
string circuit = AttributedItem::pluck("circuit", defaults);
|
||||
if (!circuit.empty() && m_circuitData.find(circuit) == m_circuitData.end()) {
|
||||
@@ -2134,10 +2125,9 @@ result_t MessageMap::readFromFile(const string& filename, bool verbose, map<stri
|
||||
}
|
||||
}
|
||||
if (result == RESULT_OK) {
|
||||
const string file = getRelativePath(filename);
|
||||
m_loadedFileInfos[file].m_hash = *hash;
|
||||
m_loadedFileInfos[file].m_size = *size;
|
||||
m_loadedFileInfos[file].m_time = *time;
|
||||
m_loadedFileInfos[filename].m_hash = *hash;
|
||||
m_loadedFileInfos[filename].m_size = *size;
|
||||
m_loadedFileInfos[filename].m_time = mtime;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -2332,10 +2322,9 @@ result_t MessageMap::executeInstructions(void (*readMessageFunc)(Message* messag
|
||||
void MessageMap::addLoadedFile(symbol_t address, const string& filename, const string& comment) {
|
||||
if (!filename.empty()) {
|
||||
vector<string>& files = m_loadedFiles[address];
|
||||
const string file = getRelativePath(filename);
|
||||
files.push_back(file);
|
||||
files.push_back(filename);
|
||||
if (!comment.empty()) {
|
||||
m_loadedFileInfos[file].m_comment = comment;
|
||||
m_loadedFileInfos[filename].m_comment = comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-19
@@ -1091,7 +1091,7 @@ class Instruction {
|
||||
|
||||
/**
|
||||
* Factory method for creating a new instance.
|
||||
* @param contextPath the path and/or filename context being loaded.
|
||||
* @param relPath the relative path and/or filename context being loaded.
|
||||
* @param type the type of the instruction.
|
||||
* @param condition the @a Condition for the instruction, or NULL.
|
||||
* @param row the definition row by field name.
|
||||
@@ -1099,7 +1099,7 @@ class Instruction {
|
||||
* @param returnValue the variable in which to store the created instance.
|
||||
* @return @a RESULT_OK on success, or an error code.
|
||||
*/
|
||||
static result_t create(const string& contextPath, const string& type,
|
||||
static result_t create(const string& relPath, const string& type,
|
||||
Condition* condition, const map<string, string>& row, const map<string, string>& defaults,
|
||||
Instruction** returnValue);
|
||||
|
||||
@@ -1156,7 +1156,7 @@ class LoadInstruction : public Instruction {
|
||||
* @param singleton whether this @a Instruction belongs to a set of instructions of which only the first one may be
|
||||
* executed for the same source file.
|
||||
* @param defaults the mapped definition defaults.
|
||||
* @param filename the name of the file to load.
|
||||
* @param filename the relative name of the file to load.
|
||||
*/
|
||||
LoadInstruction(bool singleton, const map<string, string>& defaults, const string& filename,
|
||||
Condition* condition)
|
||||
@@ -1172,7 +1172,7 @@ class LoadInstruction : public Instruction {
|
||||
|
||||
|
||||
private:
|
||||
/** the name of the file to load. */
|
||||
/** the relative name of the file to load. */
|
||||
const string m_filename;
|
||||
};
|
||||
|
||||
@@ -1207,9 +1207,8 @@ class MessageMap : public MappedFileReader {
|
||||
* @param addAll whether to add all messages, even if duplicate.
|
||||
* @param preferLanguage the preferred language to use, or empty.
|
||||
*/
|
||||
explicit MessageMap(const string& configPath, bool addAll = false, const string& preferLanguage = "")
|
||||
explicit MessageMap(bool addAll = false, const string& preferLanguage = "")
|
||||
: MappedFileReader::MappedFileReader(true),
|
||||
m_configPath(configPath),
|
||||
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();
|
||||
@@ -1231,13 +1230,6 @@ class MessageMap : public MappedFileReader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the relative file name of the given filename.
|
||||
* @param filename the name of the configuration file (including relative path).
|
||||
* @return the relative file name.
|
||||
*/
|
||||
const string getRelativePath(const string& filename) const;
|
||||
|
||||
/**
|
||||
* Add a @a Message instance to this set.
|
||||
* @param message the @a Message instance to add.
|
||||
@@ -1266,11 +1258,11 @@ class MessageMap : public MappedFileReader {
|
||||
|
||||
// @copydoc
|
||||
bool extractDefaultsFromFilename(const string& filename, map<string, string>* defaults,
|
||||
symbol_t* destAddress, unsigned int* software, unsigned int* hardware) const override;
|
||||
symbol_t* destAddress = NULL, unsigned int* software = NULL, unsigned int* hardware = NULL) const override;
|
||||
|
||||
// @copydoc
|
||||
result_t readFromFile(const string& filename, bool verbose, map<string, string>* defaults,
|
||||
string* errorDescription, size_t* hash, size_t* size, time_t* time) override;
|
||||
result_t readFromStream(istream* stream, const string& filename, time_t& mtime, bool verbose,
|
||||
map<string, string>* defaults, string* errorDescription, size_t* hash = NULL, size_t* size = NULL) override;
|
||||
|
||||
// @copydoc
|
||||
result_t addFromFile(const string& filename, unsigned int lineNo, map<string, string>* row,
|
||||
@@ -1502,9 +1494,6 @@ class MessageMap : public MappedFileReader {
|
||||
/** empty vector for @a getLoadedFiles(). */
|
||||
static vector<string> s_noFiles;
|
||||
|
||||
/** the path to the configuration files. */
|
||||
const string m_configPath;
|
||||
|
||||
/** whether to add all messages, even if duplicate. */
|
||||
const bool m_addAll;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user