intermediate: xdr mappings

This commit is contained in:
wellenvogel 2021-11-20 12:08:55 +01:00
parent d927861cdf
commit ad29c93dd2
2 changed files with 123 additions and 30 deletions

View File

@ -232,34 +232,110 @@ void GwXDRMappings::begin()
}
long n2kkey = def->n2kKey();
auto it = n2kMap.find(n2kkey);
if (it == n2kMap.end()){
LOG_DEBUG(GwLog::DEBUG,"insert mapping with key %ld",n2kkey);
GwXDRMapping *mapping = new GwXDRMapping(def, type);
n2kMap[n2kkey]=mapping;
if (it == n2kMap.end())
{
LOG_DEBUG(GwLog::DEBUG, "insert mapping with key %ld", n2kkey);
GwXDRMapping::MappingList mappings;
mappings.push_back(mapping);
n2kMap[n2kkey] = mappings;
}
else{
else
{
LOG_DEBUG(GwLog::DEBUG, "append mapping with key %ld", n2kkey);
it->second->addMappingDef(def);
it->second.push_back(mapping);
}
//for nmea0183 there could be multiple entries
//as potentially there are different units that we can handle
//so after we inserted the definition we do additional type lookups
while (type != NULL){
while (type != NULL)
{
String n183key = GwXDRMappingDef::n183key(def->xdrName,
type->xdrtype, type->xdrunit);
auto it = n183Map.find(n183key);
if (it == n183Map.end()){
if (it == n183Map.end())
{
LOG_DEBUG(GwLog::DEBUG, "insert mapping with n183key %s", n183key.c_str());
n183Map[n183key]=new GwXDRMapping(def,type);
GwXDRMapping::MappingList mappings;
mappings.push_back(mapping);
n183Map[n183key] = mappings;
}
else{
else
{
LOG_DEBUG(GwLog::DEBUG, "append mapping with n183key %s", n183key.c_str());
it->second->addMappingDef(def);
it->second.push_back(mapping);
}
type = findType(code, &typeIndex);
if (! type) break;
if (!type)
break;
mapping=new GwXDRMapping(def,type);
}
}
}
}
}
/**
* select the best matching mapping
* depending on the instance id
*/
GwXDRFoundMapping GwXDRMappings::selectMapping(GwXDRMapping::MappingList *list,int instance){
GwXDRMapping *candidate=NULL;
for (auto mit=list->begin();mit != list->end();mit++){
GwXDRMappingDef *def=(*mit)->definition;
//if there is no instance we take a mapping with instance type ignore
//otherwise we prefer a matching instance before we use auto/ignore
if (instance < 0){
if (def->instanceMode != GwXDRMappingDef::IS_IGNORE) continue;
LOG_DEBUG(GwLog::DEBUG,"found mapping %s",def->toString().c_str());
return GwXDRFoundMapping(*mit);
}
else{
switch(def->instanceMode){
case GwXDRMappingDef::IS_SINGLE:
if (def->instanceId == instance){
LOG_DEBUG(GwLog::DEBUG,"found mapping %s",def->toString().c_str());
return GwXDRFoundMapping(*mit,instance);
}
case GwXDRMappingDef::IS_AUTO:
candidate=*mit;
break;
default:
break;
}
}
}
if (candidate != NULL){
LOG_DEBUG(GwLog::DEBUG,"found mapping %s",candidate->definition->toString().c_str());
return GwXDRFoundMapping(candidate,instance);
}
return GwXDRFoundMapping();
}
GwXDRFoundMapping GwXDRMappings::getMapping(String xName,String xType,String xUnit){
//get an instance suffix from the name and separate it
int sepIdx=xName.indexOf('#');
int instance=-1;
if (sepIdx>=0){
String istr=xName.substring(sepIdx+1);
xName=xName.substring(0,sepIdx);
instance=istr.toInt();
}
if (xName == "") return GwXDRFoundMapping();
String n183Key=GwXDRMappingDef::n183key(xName,xType,xUnit);
auto it=n183Map.find(n183Key);
if (it == n183Map.end()) {
LOG_DEBUG(GwLog::DEBUG,"find n183mapping for %s,i=%d - nothing found",n183Key.c_str(),instance);
return GwXDRFoundMapping();
}
return selectMapping(&(it->second),instance);
}
GwXDRFoundMapping GwXDRMappings::getMapping(GwXDRCategory category,int selector,int field,int instance){
long n2kKey=GwXDRMappingDef::n2kKey(category,selector,field);
auto it=n2kMap.find(n2kKey);
if (it == n2kMap.end()){
LOG_DEBUG(GwLog::DEBUG,"find n2kmapping for c=%d,s=%d,f=%d,i=%d - nothing found",
(int)category,selector,field,instance);
return GwXDRFoundMapping();
}
return selectMapping(&(it->second),instance);
}

View File

@ -123,23 +123,39 @@ class GwXDRMappingDef{
rt += xdrUnit;
return rt;
}
typedef std::vector<GwXDRMappingDef*> MappingList;
private:
static bool handleToken(String tok,int index,GwXDRMappingDef *def);
};
class GwXDRMapping{
public:
GwXDRMappingDef::MappingList definitions;
GwXDRMappingDef *definition;
GwXDRType *type;
GwXDRMapping(GwXDRMappingDef *definition,GwXDRType *type){
this->definitions.push_back(definition);
this->definition=definition;
this->type=type;
}
void addMappingDef(GwXDRMappingDef *definition){
this->definitions.push_back(definition);
typedef std::vector<GwXDRMapping*> MappingList;
typedef std::map<String,MappingList> N138Map;
typedef std::map<long,MappingList> N2KMap;
};
class GwXDRFoundMapping{
public:
GwXDRMappingDef *definition=NULL;
GwXDRType *type=NULL;
int instanceId=-1;
bool empty=true;
GwXDRFoundMapping(GwXDRMappingDef *definition,GwXDRType *type){
this->definition=definition;
this->type=type;
empty=false;
}
typedef std::map<String,GwXDRMapping*> N138Map;
typedef std::map<long,GwXDRMapping*> N2KMap;
GwXDRFoundMapping(GwXDRMapping* mapping,int instance=-1){
this->definition=mapping->definition;
this->type=mapping->type;
this->instanceId=instance;
empty=false;
}
GwXDRFoundMapping(){}
};
class GwXDRMappings{
@ -148,13 +164,14 @@ class GwXDRMappings{
GwConfigHandler *config;
GwXDRMapping::N138Map n183Map;
GwXDRMapping::N2KMap n2kMap;
GwXDRFoundMapping selectMapping(GwXDRMapping::MappingList *list,int instance);
public:
GwXDRMappings(GwLog *logger,GwConfigHandler *config);
void begin();
//get the mappings
//the returned mapping will exactly contain one mapping def
GwXDRMapping getMapping(String xName,String xType,String xUnit);
GwXDRMapping getMapping(GwXDRCategory category,int selector,int field=0,int instance=0);
GwXDRFoundMapping getMapping(String xName,String xType,String xUnit);
GwXDRFoundMapping getMapping(GwXDRCategory category,int selector,int field=0,int instance=-1);
};