-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First version of a CVS reader block #223
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2012, 2024 ACIN, fortiss GmbH, Johannes Kepler University Linz, | ||
* Martin Erich Jobst | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Alois Zoitl, Monika Wenger, Martin Jobst - copy and modified from | ||
* GEN_CSV_READER | ||
*******************************************************************************/ | ||
#include "GEN_CSV_READER_fbt.h" | ||
#ifdef FORTE_ENABLE_GENERATED_SOURCE_CPP | ||
#include "GEN_CSV_READER_fbt_gen.cpp" | ||
#endif | ||
#include <errno.h> | ||
#include "devlog.h" | ||
#include "resource.h" | ||
#include "criticalregion.h" | ||
|
||
DEFINE_GENERIC_FIRMWARE_FB(GEN_CSV_READER, g_nStringIdGEN_CSV_READER); | ||
|
||
const CStringDictionary::TStringId GEN_CSV_READER::scmDataInputNames[] = { g_nStringIdQI, g_nStringIdFILE_NAME }; | ||
|
||
const CStringDictionary::TStringId GEN_CSV_READER::scmDataInputTypeIds[] = { g_nStringIdBOOL, g_nStringIdSTRING }; | ||
|
||
const CStringDictionary::TStringId GEN_CSV_READER::scmEventInputNames[] = { g_nStringIdINIT, g_nStringIdREQ }; | ||
|
||
const CStringDictionary::TStringId GEN_CSV_READER::scmEventOutputNames[] = { g_nStringIdINITO, g_nStringIdCNF }; | ||
|
||
const CIEC_STRING GEN_CSV_READER::scmOK = "OK"_STRING; | ||
const CIEC_STRING GEN_CSV_READER::scmFileAlreadyOpened = "File already opened"_STRING; | ||
const CIEC_STRING GEN_CSV_READER::scmFileNotOpened = "File not opened"_STRING; | ||
|
||
void GEN_CSV_READER::executeEvent(TEventID paEIID, CEventChainExecutionThread *const paECET) { | ||
if(scmEventINITID == paEIID) { | ||
if(QI()) { | ||
openCSVFile(); | ||
} else { | ||
closeCSVFile(); | ||
} | ||
sendOutputEvent(scmEventINITOID, paECET); | ||
} else if(scmEventREQID == paEIID) { | ||
QO() = QI(); | ||
if(QI()) { | ||
readCSVFileLine(); | ||
} | ||
sendOutputEvent(scmEventCNFID, paECET); | ||
} | ||
} | ||
|
||
GEN_CSV_READER::GEN_CSV_READER(const CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer) : | ||
CGenFunctionBlock<CFunctionBlock>(paContainer, paInstanceNameId), mDataOutputNames(nullptr), mDataOutputTypeIds(nullptr) { | ||
} | ||
|
||
GEN_CSV_READER::~GEN_CSV_READER(){ | ||
delete[] mDataOutputNames; | ||
delete[] mDataOutputTypeIds; | ||
closeCSVFile(); | ||
} | ||
|
||
void GEN_CSV_READER::readInputData(TEventID paEI) { | ||
switch(paEI) { | ||
case scmEventINITID: { | ||
readData(0, *mDIs[0], mDIConns[0]); | ||
readData(1, *mDIs[1], mDIConns[1]); | ||
break; | ||
} | ||
case scmEventREQID: { | ||
readData(0, *mDIs[0], mDIConns[0]); | ||
break; | ||
} | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
void GEN_CSV_READER::writeOutputData(TEventID paEO) { | ||
switch(paEO) { | ||
case scmEventINITOID: { | ||
writeData(0, *mDOs[0], mDOConns[0]); | ||
writeData(1, *mDOs[1], mDOConns[1]); | ||
break; | ||
} | ||
case scmEventCNFID: { | ||
writeData(0, *mDOs[0], mDOConns[0]); | ||
writeData(1, *mDOs[1], mDOConns[1]); | ||
for(TPortId i = 2; i < getFBInterfaceSpec().mNumDOs; i++){ | ||
writeData(i, *mDOs[i], mDOConns[i]); | ||
} | ||
break; | ||
} | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
bool GEN_CSV_READER::createInterfaceSpec(const char *paConfigString, SFBInterfaceSpec &paInterfaceSpec) { | ||
const char *acPos = strrchr(paConfigString, '_'); | ||
if(nullptr != acPos){ | ||
acPos++; | ||
paInterfaceSpec.mNumDOs = static_cast<TPortId>(forte::core::util::strtoul(acPos, nullptr, 10) + 2); // we have in addition to the SDs a QI and FILE_NAME data inputs | ||
|
||
mDataOutputNames = new CStringDictionary::TStringId[paInterfaceSpec.mNumDOs]; | ||
mDataOutputTypeIds = new CStringDictionary::TStringId[paInterfaceSpec.mNumDOs]; | ||
|
||
mDataOutputNames[0] = g_nStringIdQO; | ||
mDataOutputTypeIds[0] = g_nStringIdBOOL; | ||
mDataOutputNames[1] = g_nStringIdSTATUS; | ||
mDataOutputTypeIds[1] = g_nStringIdSTRING; | ||
|
||
generateGenericDataPointArrays("RD_", &(mDataOutputTypeIds[2]), &(mDataOutputNames[2]), paInterfaceSpec.mNumDOs - 2); | ||
|
||
//create the interface Specification | ||
paInterfaceSpec.mNumEIs = 2; | ||
paInterfaceSpec.mEINames = scmEventInputNames; | ||
paInterfaceSpec.mNumEOs = 2; | ||
paInterfaceSpec.mEONames = scmEventOutputNames; | ||
paInterfaceSpec.mDINames = scmDataInputNames; | ||
paInterfaceSpec.mDIDataTypeNames = scmDataInputTypeIds; | ||
paInterfaceSpec.mNumDOs = 2; | ||
paInterfaceSpec.mDONames = mDataOutputNames; | ||
paInterfaceSpec.mDODataTypeNames = mDataOutputTypeIds; | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
void GEN_CSV_READER::openCSVFile() { | ||
QO() = false_BOOL; | ||
if(!mCSVFile.is_open()) { | ||
mCSVFile.open(FILE_NAME().getStorage().c_str()); | ||
if(mCSVFile.is_open()) { | ||
QO() = true_BOOL; | ||
STATUS() = scmOK; | ||
DEVLOG_INFO("[GEN_CSV_READER]: File %s successfully opened\n", FILE_NAME().getStorage().c_str()); | ||
} else { | ||
const char* errorCode = strerror(errno); | ||
STATUS() = CIEC_STRING(errorCode, strlen(errorCode)); | ||
DEVLOG_ERROR("[GEN_CSV_READER]: Couldn't open file %s. Error: %s\n", FILE_NAME().getStorage().c_str(), STATUS().getStorage().c_str()); | ||
} | ||
} else { | ||
STATUS() = scmFileAlreadyOpened; | ||
DEVLOG_ERROR("[GEN_CSV_READER]: Can't open file %s since it is already opened\n", FILE_NAME().getStorage().c_str()); | ||
} | ||
} | ||
|
||
void GEN_CSV_READER::closeCSVFile() { | ||
QO() = CIEC_BOOL(false); | ||
mCSVFile.close(); | ||
STATUS() = scmOK; | ||
DEVLOG_INFO("[GEN_CSV_READER]: File %s successfully closed\n", FILE_NAME().getStorage().c_str()); | ||
} | ||
|
||
void GEN_CSV_READER::readCSVFileLine() { | ||
if(mCSVFile.is_open()) { | ||
std::string line; | ||
if(getline(mCSVFile, line)){ | ||
std::size_t oldPos = 0; | ||
|
||
for(std::size_t i = 0; i < getNumRD(); i++) { | ||
std::size_t newPos = line.find(';', oldPos); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seeing this, you implicitly assume a German-language CSV file, correct? |
||
if (newPos != std::string::npos){ | ||
std::string value = line.substr(oldPos, newPos - oldPos); | ||
getDI(i+2)->unwrap().fromString(value.c_str()); | ||
} else if (oldPos < line.length()){ | ||
std::string value = line.substr(oldPos); | ||
getDI(i+2)->unwrap().fromString(value.c_str()); | ||
} else { | ||
CIEC_ANY *value = CTypeLib::createDataTypeInstance(getDI(i+2)->getTypeNameID(), nullptr); | ||
if (value) { getDI(i+2)->setValue(*value); } | ||
delete value; | ||
} | ||
oldPos = newPos + 1; | ||
} | ||
QO() = true_BOOL; | ||
} else { | ||
QO() = false_BOOL; | ||
STATUS() = "Could not read line!"_STRING; | ||
} | ||
} else { | ||
QO() = false_BOOL; | ||
STATUS() = scmFileNotOpened; | ||
DEVLOG_ERROR("[GEN_CSV_READER]: Can't write to file %s since it is not opened\n", FILE_NAME().getStorage().c_str()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2012, 2024 ACIN, fortiss GmbH, Johannes Kepler University Linz, | ||
* Martin Erich Jobst | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Alois Zoitl, Monika Wenger, Martin Jobst - copy and modified from | ||
* GEN_CSV_WRITER | ||
*******************************************************************************/ | ||
#pragma once | ||
|
||
#include "genfb.h" | ||
#include <stdio.h> | ||
#include "../../arch/forte_fileio.h" | ||
#include <vector> | ||
#include <fstream> | ||
#include <iostream> | ||
|
||
class GEN_CSV_READER : public CGenFunctionBlock<CFunctionBlock> { | ||
DECLARE_GENERIC_FIRMWARE_FB(GEN_CSV_READER) | ||
|
||
protected: | ||
CIEC_BOOL &QI(){ | ||
return *static_cast<CIEC_BOOL*>(getDI(0)); | ||
} | ||
|
||
CIEC_STRING &FILE_NAME(){ | ||
return *static_cast<CIEC_STRING*>(getDI(1)); | ||
} | ||
|
||
static const CStringDictionary::TStringId scmDataInputNames[]; | ||
static const CStringDictionary::TStringId scmDataInputTypeIds[]; | ||
|
||
CIEC_BOOL &QO(){ | ||
return *static_cast<CIEC_BOOL*>(getDO(0)); | ||
} | ||
|
||
CIEC_STRING &STATUS(){ | ||
return *static_cast<CIEC_STRING*>(getDO(1)); | ||
} | ||
|
||
TPortId getNumRD() const { | ||
return getFBInterfaceSpec().mNumDOs - 2; | ||
} | ||
|
||
static const TEventID scmEventINITID = 0; | ||
static const TEventID scmEventREQID = 1; | ||
static const CStringDictionary::TStringId scmEventInputNames[]; | ||
|
||
static const TEventID scmEventINITOID = 0; | ||
static const TEventID scmEventCNFID = 1; | ||
static const CStringDictionary::TStringId scmEventOutputNames[]; | ||
|
||
void executeEvent(TEventID paEIID, CEventChainExecutionThread *const paECET) override; | ||
|
||
void readInputData(TEventID paEI) override; | ||
void writeOutputData(TEventID paEO) override; | ||
|
||
bool createInterfaceSpec(const char *paConfigString, SFBInterfaceSpec &paInterfaceSpec) override; | ||
|
||
public: | ||
GEN_CSV_READER(const CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer); | ||
~GEN_CSV_READER() override; | ||
|
||
private: | ||
|
||
void openCSVFile(); | ||
void closeCSVFile(); | ||
void readCSVFileLine(); | ||
|
||
std::ifstream mCSVFile; | ||
|
||
CStringDictionary::TStringId *mDataOutputNames; | ||
CStringDictionary::TStringId *mDataOutputTypeIds; | ||
|
||
static const CIEC_STRING scmOK; | ||
static const CIEC_STRING scmFileAlreadyOpened; | ||
static const CIEC_STRING scmFileNotOpened; | ||
|
||
std::vector<char> writeBuffer; | ||
|
||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are calling c_str() several times. I would suggest to store the result of the first call and use it later, as FILE_NAME will probably not modified in this function anymore