question

Upvote
Accepted
154 18 24 35

How to get all possible enum values in RFA C++?

In RFA C++, I can use rfa::rdm::RDMFieldDictionary::displayValueFor(fieldId,enumVal) to get the textual display value for an enum integer value ((e.g. 840 => "USD" for the CURRENCY(15) field)).

However, I would like to find the integer value for a textual display value (i.e. "USD" => 840) and get all the possible enum values for a FID.

How can I do this in RFA C++?

treprfarfa-apic++
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
Accepted
78.6k 248 52 74

RFA C++ doesn't provide interfaces to convert a textual display string to the integer value or get all possible enum values.

However, you can modify the source code files (RDMDict.cpp, and RDMDictDef.cpp in Examples\Common folder) in RFA C++ package to support this behaviour.

  1. Adding a new std::map into Examples\Common\RDMDictDef.h file to increase the searching performance

    // RFA Includes
    #include "Data/DataBuffer.h"
    #include <list>
    #include <map>

    typedef std::map< rfa::common::UInt16, rfa::common::RFA_String > EnumValues;
    typedef std::map<rfa::common::RFA_String, rfa::common::UInt16> ExpandValues;
  2. Declare a new variable for the new map

    protected:

    EnumValues _enumValMap;
    ExpandValues _exValMap;
  3. Insert an enumeration into this map
    void insertEnumVal()
    {
    _enumValMap.insert( EnumValues::value_type( _enumVal, _enumString ) );
    _exValMap.insert(ExpandValues::value_type(_enumString, _enumVal));

    }

    void insertEnumVal( rfa::common::UInt16 enumVal, const rfa::common::RFA_String& enumString )
    {
    _enumString = enumString;
    _enumValMap.insert( EnumValues::value_type( enumVal, _enumString ) );
    _exValMap.insert(ExpandValues::value_type(_enumString, enumVal));
    }

  4. Define a new function to search this map
    class RDMEnumDef
    {
    public:
    void setDisplayName( rfa::common::RFA_String& s ) { _enumString = s; }

    bool getEnumValueEx(const rfa::common::RFA_String& s, rfa::common::UInt16& enumVal) const
    {

    ExpandValues::const_iterator cit = _exValMap.find( s );
    if(cit != _exValMap.end())
    {
    enumVal = cit->second;
    return true;
    }else
    {
    return false;
    }

    }

    }

To use this class, the application must include the following headers:

#include "../Common/RDMDict.h"

#include "../Common/RDMDictDef.h"

#include "../Common/RDMDictionaryDecoder.h"

Then, adding RDMDict.cpp, RDMDictDef.cpp, and RDMDictionaryDecoder.cpp from Examples\Common directory into your project.

The following snippet shows how to use this class:

int main(int argc, char* argv[])

{

RDMFieldDict *_dict = new RDMFieldDict();

RDMFileDictionaryDecoder *_dictDecoder = new RDMFileDictionaryDecoder(*_dict);

bool _ret = _dictDecoder->load("c:\\var\\triarch\\RDMFieldDictionary", "c:\\var\\triarch\\enumtype.def");

rfa::common::UInt16 _enum;

//Find the integer value for a textual display value

_ret = _dict->getFieldDef("RDN_EXCHID")->getEnumDef()->getEnumValueEx("CFS", _enum);

if (_ret == true)

printf("%d\n", _enum);

else

printf("Not found");

//Get all the possible enum values for a FID

const EnumValues& _enumMap = _dict->getFieldDef("RDN_EXCHID")->getEnumDef()->values();

for (EnumValues::const_iterator it = _enumMap.begin(); it != _enumMap.end(); ++it)

std::cout << it->first << " => " << it->second.c_str() << '\n';

}

You can use RDMNetworkDictionaryDecoder instead of RDMFileDictionaryDecoder when downloading the data dictionary from the network.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
103 0 2 1

RFA C++ does not provide any interface that would directly provide the functionality you are looking for. However, you can do it all yourself. For example, use the const RDMFidDef& getFidDef( Int32 fid ) and pass in the FID# you are interested in. Then iterate over all possible enum values using the RDMFidDef::displayValueFor( Int enumval ). Based on this iteration create a hash table of enum vals to enum strings.

Understand this may look "funny" as the range for the enum values is Int (64 bits) but from the practical point of view, the actual enum values are not larger than 2000 or so. Please see the enumtype.def file for details.

The above solution works with the network and local file dictionaries as long as RFA has loaded them.

You may also use the enumtype.def file, outside of RFA. Though the content of this file may be changing over time with some additions, the format of this file does not change at all. So your text processing tool will work with future releases.

Hope this helps.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.