diff --git a/modules/fieldClassifier/src/fieldClassifier.cpp b/modules/fieldClassifier/src/fieldClassifier.cpp index 0b4e2ac..3125d90 100644 --- a/modules/fieldClassifier/src/fieldClassifier.cpp +++ b/modules/fieldClassifier/src/fieldClassifier.cpp @@ -281,6 +281,143 @@ void FieldClassifier::loadIP( + ex.what()); } } +void FieldClassifier::fillInputFieldsToOutput( + std::optional& input, + std::optional& output, + std::string& templateStr) + +{ + // split template to vector by commas + std::vector templateFields; + size_t pos = 0; + std::string strCopy = templateStr; + if (templateStr.back() != ',') { + strCopy += ','; // Add a trailing comma to ensure the last field is processed + } + while ((pos = strCopy.find(',')) != std::string::npos) { + // Extract the field + std::string field = strCopy.substr(0, pos); + strCopy.erase(0, pos + 1); + if (!field.empty()) { // ignore empty fields + templateFields.push_back(field); + } + } + // for each field, get data from input and set to output + for (const auto& field : templateFields) { + // split field by space to get field name + size_t spacePos = field.find(' '); + if (spacePos == std::string::npos) { + throw std::runtime_error( + "FieldClassifier: Invalid Unirec field format in template: " + field); + } + std::string fieldName = field.substr(spacePos + 1); + std::string fieldType = field.substr(0, spacePos); + + auto fieldId = static_cast(ur_get_id_by_name(fieldName.c_str())); + if (fieldId == UR_E_INVALID_NAME) { + throw std::runtime_error("FieldClassifier: Invalid Unirec field name: " + fieldName); + } + try { + if (fieldType == "string") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "uint8") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "uint16") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "uint32") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "uint64") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "ipaddr") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "int8") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "int16") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "int32") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "int64") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "char") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "float") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "double") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "macaddr") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "time") { + auto value = input->getFieldAsType(fieldId); + output->setFieldFromType(value, fieldId); + } else if (fieldType == "bytes") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "int8*") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "int16*") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "int32*") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "int64*") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "uint8*") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "uint16*") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "uint32*") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "uint64*") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "float*") { + Nemea::UnirecArray const arr = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else if (fieldType == "double*") { + Nemea::UnirecArray const arr + = input->getFieldAsUnirecArray(fieldId); + output->setFieldFromUnirecArray(arr, fieldId); + } else { + throw std::runtime_error( + "FieldClassifier: Unsupported Unirec field type in template: " + fieldType); + } + + } catch (const std::exception& ex) { + throw std::runtime_error( + std::string("FieldClassifier: Unable to copy field '") + field + + "' from input to output Unirec record: " + ex.what()); + } + } +} void FieldClassifier::getDataFromPlugins(std::optional& unirecView) { diff --git a/modules/fieldClassifier/src/fieldClassifier.hpp b/modules/fieldClassifier/src/fieldClassifier.hpp index 5dc4ef3..7ed2f8d 100644 --- a/modules/fieldClassifier/src/fieldClassifier.hpp +++ b/modules/fieldClassifier/src/fieldClassifier.hpp @@ -76,6 +76,11 @@ class FieldClassifier { */ void handleParams(int argc, char** argv, argparse::ArgumentParser& parser); + void fillInputFieldsToOutput( + std::optional& input, + std::optional& output, + std::string& templateStr); + private: std::vector m_plugins = g_PLUGINS; diff --git a/modules/fieldClassifier/src/main.cpp b/modules/fieldClassifier/src/main.cpp index 31de888..4045d88 100644 --- a/modules/fieldClassifier/src/main.cpp +++ b/modules/fieldClassifier/src/main.cpp @@ -62,6 +62,15 @@ static void processNextRecord( throw std::runtime_error(std::string("Unable to create output Unirec record")); return; } + auto* templateDef = input.getTemplate(); + if (templateDef == nullptr) { + throw std::runtime_error(std::string("Unable to get template from trap input")); + } + + // convert template to string and append new fileds + std::string stringTemp = static_cast(ur_template_string(templateDef)); + + fieldClassifier.fillInputFieldsToOutput(inputUnirecView, unirecRecord, stringTemp); // populate Unirec record with data from modules try { diff --git a/modules/fieldClassifier/src/plugins/plugin.hpp b/modules/fieldClassifier/src/plugins/plugin.hpp index be8eef8..43e16d0 100644 --- a/modules/fieldClassifier/src/plugins/plugin.hpp +++ b/modules/fieldClassifier/src/plugins/plugin.hpp @@ -58,11 +58,11 @@ enum DataType : uint8_t { CHAR, FLOAT, DOUBLE, - // IPADDR, - // MACADDR, - // TIME, + IPADDR, + MACADDR, + TIME, STRING, - // BYTES + BYTES }; /**