/** * This class is an implementation of the C++ bindings for LCM. * LCM capabilities are available for a program written in C++ * by using methods belonging to the Clcm class. *

A Clcm object in C++ can encapsulate a native LCM object * which can be memory-resident or persistent (using the XSM C API) * or a file. A LCM or XSM native object can contains dictionaries * (aka associative tables or hash tables) and lists. *

* * @author Alain Hebert, Ecole Polytechnique de Montreal (2024) */ #ifndef Clcm_HXX #define Clcm_HXX #include // for __GLIBCXX__ #ifdef __GLIBCXX__ // for memory management with shared_ptr # include #else # ifdef __IBMCPP__ # define __IBMCPP_TR1__ # endif # include #endif #include #include #include #include #include #include #include #include #include #include #include "LCMexception.hxx" extern "C" { #include #include "lcm.h" } #define IntPtr std::shared_ptr #define FloatPtr std::shared_ptr #define StringPtr std::shared_ptr #define DoublePtr std::shared_ptr #define BoolPtr std::shared_ptr #define ComplexPtr std::shared_ptr< std::complex[] > #define StringVecPtr std::shared_ptr< std::vector > #define ClcmPtr std::shared_ptr // support for pinning. #define AnyPtr std::variant #define IntPtrConst std::shared_ptr #define FloatPtrConst std::shared_ptr #define StringPtrConst std::shared_ptr #define DoublePtrConst std::shared_ptr #define BoolPtrConst std::shared_ptr #define ComplexPtrConst std::shared_ptr > namespace ganlib { /** * This class is an implementation of the C++/shared_ptr bindings for LCM. * LCM capabilities are available for a program written in C++ * by using methods belonging to the Clcm class. These methods * encapsulate the LCM C API calls used as "extern"C" functions. *

A Clcm object in C++ can encapsulate a native LCM object * which can be memory-resident or persistent (using the XSM C API) * or a file. A LCM or XSM native object can contains dictionaries * (aka associative tables or hash tables) and lists. *

* The Clcm class uses predefined declarations for some datatypes: * *   *   *   *   *   *   *   *   *
#define IntPtr:std::shared_ptr
#define FloatPtr:std::shared_ptr
#define StringPtr:std::shared_ptr
#define DoublePtr:std::shared_ptr
#define BoolPtr:std::shared_ptr
#define ComplexPtr:std::shared_ptr< complex[] >
#define StringVecPtr:std::shared_ptr< std::vector >
#define ClcmPtr:std::shared_ptr
*

* Moreover, get methods are constructing shared arrays that cannot be modified in the calling C++ * code. To prevent this, they are declared const using the following predefined declarations: * *   *   *   *   *   *   *
#define IntPtrConst:std::shared_ptr
#define FloatPtrConst:std::shared_ptr
#define StringPtrConst:std::shared_ptr
#define DoublePtrConst:std::shared_ptr
#define BoolPtrConst:std::shared_ptr
#define ComplexPtrConst:std::shared_ptr[] >
*

* * @author Alain Hebert, Ecole Polytechnique de Montreal (2010) */ class Clcm { public: /** * Use this constructor to create a Clcm object of a specified type. * The new LCM object is open in modification mode and is in a state * such that the isNew() method will return true. * If a XSM file name exists, the Clcm object is pointing to * this file open in "READ-ONLY" mode and is in a state * such that the isNew() method will return false. * If the type is "LCM_IMP" or "XSM_IMP", the new * LCM object is open in modification mode and the isNew() * method will return false. *

* A Clcm object is created using a construct similar to the following one: *

   * ClcmPtr myNewClcm = ClcmPtr(new Clcm("XSM_IMP_ASCII", "Multicompo", "./"));
   * 
* where a XSM file is imported from ASCII file ./Multicompo. * * @param stype type of the new Clcm object. This variable is chosen among * the following values: * * @param myName creation name of the new Clcm object * @param myPath path to access the associated file. This can be a sequential import * file (with "_" prefix), an "XSM", "BINARY", * "ASCII" or "DA" file. Set to "./" to work * in the current directory. */ Clcm(const std::string stype, const std::string myName, const std::string myPath); /// @cond DEV Clcm(lcm *, Clcm *, const int_32, const std::string, const int_32, const std::string); /// @endcond /** * Use this constructor to create a clone of an existing Clcm object. This is a deep-copy * operation. A clone is created using the following construct: *
   * ClcmPtr myClcmClone = ClcmPtr(new Clcm("LCM", myClcm));
   * 
* @param stype type of the new Clcm object. This variable is chosen among * the following values: * * @param myClcm existing ClcmPtr object accessed in read-only mode. This object must me of * LCM or XSM type. */ Clcm(const std::string stype, ClcmPtr myClcm); /** * Use this constructor to encapsulate an open LCM or XSM object into a Clcm object. The * existing LCM or XSM object is not garbage collected (it may belong to another Clcm object). * @param mylcm existing LCM or XSM object. * @param type type of object (=1: LCM; =2:XSM). * @param access access mode of object (=1: ; =2:). * @param OSname operating system name of object. */ Clcm(lcm *mylcm, const int_32 type, const int_32 access, const std::string OSname); /** Close and destroy a Clcm object if in modification mode; close and * keep a Clcm object if in read-only mode. */ ~Clcm(); /** Export a Clcm object into an ostream (ascii stream). This method is not available for * file-type Clcm objects. A Clcm object can be dumped to the standard output using: *
   * cout << myClcm;
   * 
* @param s initial std::ostream objet. * @param myClcm ClcmPtr object to export. * @return final std::ostream objet including the ClcmPtr object. */ friend std::ostream & operator<<(std::ostream &s, ClcmPtr myClcm); /** Serialize and save the object content on a sequential file. This method is not * available for file-type Clcm objects. The name of the sequential file is * the catenation of "_" with the name of the Clcm object. * @param stype type of the export file. This variable is chosen among * the following values: * */ void expor(const std::string stype); /** Serialize and save the object content on a sequential file. This method is not * available for file-type Clcm objects. * @param stype type of the export file. This variable is chosen among * the following values: * * @param new_name name of the sequential file. This name must begin by * character "_". */ void expor(const std::string stype, const std::string new_name); /** Cause an exception (used to debug XABORT in C++). */ void except(); /** Return the name of the Clcm object. */ std::string getName() throw(); /** Return the path to access the associated file. */ std::string getPath() throw(); /** Return the type of the Clcm object. * @return =1: memory-resident LCM object; =2: persistent LCM object; * =3: binary sequential file; =4: ASCII sequential file; =5 binary * direct-access file. */ int_32 getType() throw(); /** Return the length of a list-type Clcm object. This method is not * available for file-type Clcm objects. * @return =-1: dictionary; >=1: length of the list-type Clcm object. */ int_32 getLength(); /** Return the name of the accessible directory of a dictionary-type * Clcm object. This method is not available for file-type Clcm objects. * @return ="/" for a dictionary on root or name of the accessible * directory. */ std::string getDirectory(); /** Return the access type of a Clcm object. * @return =0: the object is closed; =1: the object is open in modification * mode; =2: the object is open in read-only mode. */ int_32 getAccess(); /** Return the number of words in a record of a direct access-type Clcm object. */ int_32 getLrda() throw(); /** Return the original version of the imported object. */ int_32 getVersion() throw(); /** Return true if the a dictionary-type Clcm object is empty. This method * is not available for file-type Clcm objects. */ bool isEmpty(); /** Return true if the dictionary-type Clcm object is new. This method * is not available for file-type Clcm objects. */ bool isNew() throw(); /** Open a new Clcm object or reopen an existing Clcm object already closed by * the close("KEEP") method. In this case, the Clcm object is reopen * in a state such as the isNew() method will return false. * @param saccess type of open. This variable is chosen among the following * values: * */ void open(const std::string saccess); /** Close a Clcm object. * @param saccess ="KEEP": close without destruction of the object * content; ="DESTROY": close with destruction of the object content. */ void close(const std::string saccess); /** * Return the length of a block of information in a dictionary-type * Clcm object. This method is not available for file-type Clcm objects. * @param key key identification of the block in the dictionary * @return the number of components for an elementary block; -1 for * a daughter dictionary; 0: the block does't exist; length of the list * for a daughter list; length in characters for a string array. */ int_32 length(const std::string key); /** * Return the length of a block of information in a list-type Clcm object. * This method is not available for file-type Clcm objects. * @param iset index of the block in the list. The first list element is * stored at index 0. * @return the number of components for an elementary block; -1 for * a daughter dictionary; 0: the block does't exist; length of the list * for a daughter list; length in characters for a string array. */ int_32 length(const int_32 iset); /** * Return the type of a block of information in a dictionary-type * Clcm object. This method is not available for file-type Clcm objects. * @param key key identification of the block in the dictionary * @return =0: dictionary; =1: integer (int_32); =2: real number (float); * =3: string; =4: real number (double); =5: boolean; =6: Complex object; * =10: list. */ int_32 type(const std::string key); /** * Return the type of a block of information in a list-type Clcm object. * This method is not available for file-type Clcm objects. * @param iset index of the block in the list. The first list element is * stored at index 0. * @return =0: dictionary; =1: integer (int_32); =2: real number (float); * =3: string; =4: real number (double); =5: boolean; =6: Complex object; * =10: list. */ int_32 type(const int_32 iset); /** Print the table of contents of a dictionary- or list-type Clcm object. * This method is not available for file-type Clcm objects. */ void lib(); /** Validate a dictionary- or list-type Clcm object. Detect possible memory * corruption. * This method is not available for file-type Clcm objects. */ void val(); /** Set a daughter dictionary-type Clcm object from a dictionary-type Clcm * object. This method is not available for file-type Clcm objects. * @param key key identification of the daughter Clcm object in the dictionary * @return daughter ClcmPtr object of dictionary or list type. */ ClcmPtr setDictionary(const std::string key); /** Set a daughter dictionary-type Clcm object from a list-type Clcm * object. This method is not available for file-type Clcm objects. * @param iset index of the daughter Clcm object in the list. The first list * element is stored at index 0. * @return daughter ClcmPtr object of dictionary or list type. */ ClcmPtr setDictionary(const int_32 iset); /** Set a daughter list-type Clcm object from a dictionary-type Clcm object. * This method is not available for file-type Clcm objects. * @param key key identification of the daughter Clcm object in the dictionary * @param ilong initial length of the heterogeneous list * @return daughter ClcmPtr object of dictionary or list type. */ ClcmPtr setList(const std::string key, const int_32 ilong); /** Set a daughter list-type Clcm object from a list-type Clcm object * This method is not available for file-type Clcm objects. * @param iset index of the daughter Clcm object in the list. The first list * element is stored at index 0. * @param ilong initial length of the heterogeneous list * @return daughter ClcmPtr object of dictionary or list type. */ ClcmPtr setList(const int_32 iset, const int_32 ilong); /** Recover a daughter Clcm object from an existing dictionary-type Clcm object. * This method is not available for file-type Clcm objects. * @param key key identification of the daughter Clcm object in the dictionary * @return daughter ClcmPtr object of dictionary or list type. */ ClcmPtr getClcm(const std::string key); /** Recover a daughter Clcm object from an existing list-type Clcm object. * This method is not available for file-type Clcm objects. * @param iset index of the daughter Clcm object in the list. The first list * element is stored at index 0. * @return daughter ClcmPtr object of dictionary or list type. */ ClcmPtr getClcm(const int_32 iset); /** Recover an integer array from a dictionary-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getInt. This method is not available for file-type Clcm objects. *

* Example: An integer array named "myArray" is read from * Clcm object named multicompo using *

   *  IntPtrConst ia = multicompo->getInt("myArray");
   *  for(int i = 0; i < multicompo->length("myArray"); ++i) 
   *     cout << "ia(" << i << ")=" << ia[i] << endl;
   * 
* @param key key identification of the integer array in the dictionary * @return array of integer values stored as IntPtr object. */ IntPtrConst getInt(const std::string key); /** Recover an integer array from a list-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getInt. This method is not available for file-type Clcm objects. * @param iset index of the integer array in the list. The first list element * is stored at index 0. * @return array of integer values stored as IntPtr object. */ IntPtrConst getInt(const int_32 iset); /** Recover a single precision real array from a dictionary-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getFloat. This method is not available for file-type Clcm objects. * @param key key identification of the real array in the dictionary * @return array of single precision real values stored as FloatPtr object. */ FloatPtrConst getFloat(const std::string key); /** Recover a single precision real array from a list-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getFloat. This method is not available for file-type Clcm objects. * @param iset index of the real array in the list. The first list element * is stored at index 0. * @return array of single precision real values stored as FloatPtr object. */ FloatPtrConst getFloat(const int_32 iset); /** Recover a string pointer from a dictionary-type Clcm object. * General rule: Never try to modify, deallocate or free the string returned * by getString. This method is not available for file-type Clcm objects. * @param key key identification of the character array in the dictionary * @return character information stored as StringPtr object. */ StringPtrConst getString(const std::string key); /** Recover a string pointer from a list-type Clcm object. * General rule: Never try to modify, deallocate or free the string returned * by getString. This method is not available for file-type Clcm objects. * @param iset index of the integer array in the list. The first list element * is stored at index 0. * @return character information stored as StringPtr object. */ StringPtrConst getString(const int_32 iset); /** Recover a vector-of-string pointer from a dictionary-type Clcm object. * General rule: Never try to modify, deallocate or free the vector-of-string returned * by getVecString. This method is not available for file-type Clcm objects. * @param key key identification of the character array in the dictionary * @param size number of components in the vector-of-string * @return vector-of-string containing the character information stored as * StringVecPtr object. */ StringVecPtr getVecString(const std::string key, const int_32 size); /** Recover a vector-of-string pointer from a list-type Clcm object. * General rule: Never try to modify, deallocate or free the vector-of-string returned * by getVecString. This method is not available for file-type Clcm objects. * @param iset index of the integer array in the list. The first list element * is stored at index 0. * @param size number of components in the vector-of-string * @return vector-of-string containing the character information stored as * StringVecPtr object. */ StringVecPtr getVecString(const int_32 iset, const int_32 size); /** Recover a double precision real array from a dictionary-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getDouble. This method is not available for file-type Clcm objects. * @param key key identification of the double precision array in the dictionary * @return array of double precision real values stored as DoublePtr object. */ DoublePtrConst getDouble(const std::string key); /** Recover a double precision real array from a list-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getDouble. This method is not available for file-type Clcm objects. * @param iset index of the double precision array in the list. The first list element * is stored at index 0. * @return array of double precision real values stored as DoublePtr object. */ DoublePtrConst getDouble(const int_32 iset); /** Recover a boolean array from a dictionary-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getBool. This method is not available for file-type Clcm objects. * @param key key identification of the boolean array in the dictionary * @return array of boolean values stored as BoolPtr object. */ BoolPtrConst getBool(const std::string key); /** Recover a boolean array from a list-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getBool. This method is not available for file-type Clcm objects. * @param iset index of the boolean array in the list. The first list element * is stored at index 0. * @return array of boolean values stored as BoolPtr object. */ BoolPtrConst getBool(const int_32 iset); /** Recover a complex array from a dictionary-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getComplex. This method is not available for file-type Clcm objects. * @param key key identification of the complex array in the dictionary * @return array of complex values stored as ComplexPtr object. */ ComplexPtrConst getComplex(const std::string key); /** Recover a complex array from a list-type Clcm object. * General rule: Never try to modify, deallocate or free the object returned * by getComplex. This method is not available for file-type Clcm objects. * @param iset index of the complex array in the list. The first list element * is stored at index 0. * @return array of complex values stored as ComplexPtr object. */ ComplexPtrConst getComplex(const int_32 iset); /** Recover a vector-of-string pointer containing the keys of a dictionary-type Clcm * object. General rule: Never try to modify, deallocate or free the vector-of-string * returned by keys. This method is not available for file-type or list-type * Clcm objects. * @return StringVecPtr of a vector-of-string containing the dictionary keys */ StringVecPtr keys(); /** Store an integer array in a dictionary-type Clcm object. This method is not * available for file-type Clcm objects. *

* Example: An integer array named "myIntArray" is inserted in * Clcm object named multicompo using *

   *  static int_32 myStaticArray[] = {33, 22, 11, 89};
   *  IntPtr myIntPtr = IntPtr(new int_32[4]);
   *  for(int i = 0; i < 4; ++i) myIntPtr[i] = myStaticArray[i];
   *  multicompo->put("myIntArray", myIntPtr, 4);
   * 
* @param key key identification of the block in the dictionary * @param myArray integer array stored as IntPtr object. * @param myLength number of components in integer array. */ void put(const std::string key, IntPtr myArray, const int_32 myLength); /** Store an integer array in a list-type Clcm object. This method is not available * for file-type Clcm objects. * @param iset index of the integer array in the list. The first list element * is stored at index 0. * @param myArray integer array stored as IntPtr object. * @param myLength number of components in integer array. */ void put(const int_32 iset, IntPtr myArray, const int_32 myLength); /** Store a single precision real array in a dictionary-type Clcm object. This method * is not available for file-type Clcm objects. * @param key key identification of the block in the dictionary * @param myArray single precision real array stored as FloatPtr object. * @param myLength number of components in real array. */ void put(const std::string key, FloatPtr myArray, const int_32 myLength); /** Store a single precision real array in a list-type Clcm object. This method is * not available for file-type Clcm objects. * @param iset index of the real array in the list. The first list element * is stored at index 0. * @param myArray single precision real array stored as FloatPtr object. * @param myLength number of components in real array. */ void put(const int_32 iset, FloatPtr myArray, const int_32 myLength); /** Store a string pointer in a dictionary-type Clcm object. This method is not available * for file-type Clcm objects. * @param key key identification of the character array in the dictionary * @param myArray character information stored as StringPtr object. */ void put(const std::string key, StringPtr myArray); /** Store a string pointer in a list-type Clcm object. This method is not available for * file-type Clcm objects. * @param iset index of the string in the list. The first list element is stored at index 0. * @param myArray character information stored as StringPtr object. */ void put(const int_32 iset, StringPtr myArray); /** Store a vector-of-string pointer in a dictionary-type Clcm object. * This method is not available for file-type Clcm objects. * @param key key identification of the character array in the dictionary * @param myArray vector-of-string containing the character information stored as * StringVecPtr object. */ void put(const std::string key, StringVecPtr myArray); /** Store a vector-of-string pointer in a list-type Clcm object. * This method is not available for file-type Clcm objects. * @param iset index of the character array in the list. The first list element * is stored at index 0. * @param myArray vector-of-string containing the character information stored as * StringVecPtr object. */ void put(const int_32 iset, StringVecPtr myArray); /** Store a double precision real array in a dictionary-type Clcm object. This method is * not available for file-type Clcm objects. * @param key key identification of the double precision array in the dictionary * @param myArray double precision array stored as DoublePtr object. * @param myLength number of components in double precision array. */ void put(const std::string key, DoublePtr myArray, const int_32 myLength); /** Store a double precision real array in a list-type Clcm object. This method is * not available for file-type Clcm objects. * @param iset index of the double precision array in the list. The first list element * is stored at index 0. * @param myArray double precision array stored as DoublePtr object. * @param myLength number of components in double precision array. */ void put(const int_32 iset, DoublePtr myArray, const int_32 myLength); /** Store a boolean array in a dictionary-type Clcm object. This method is not * available for file-type Clcm objects. * @param key key identification of the block in the dictionary * @param myArray boolean array stored as BoolPtr object. * @param myLength number of components in boolean array. */ void put(const std::string key, BoolPtr myArray, const int_32 myLength); /** Store a boolean array in a list-type Clcm object. This method is not * available for file-type Clcm objects. * @param iset index of the boolean array in the list. The first list element * is stored at index 0. * @param myArray boolean array stored as BoolPtr object. * @param myLength number of components in boolean array. */ void put(const int_32 iset, BoolPtr myArray, const int_32 myLength); /** Store a complex array in a dictionary-type Clcm object. This method is not * available for file-type Clcm objects. *

* Example: A complex array named "myComplArray" is inserted in * Clcm object named multicompo using *

   *  ComplexPtr myComplexPtr = ComplexPtr(new complex[2]);
   *  myComplexPtr[0] = complex(3.3, 8.9);
   *  myComplexPtr[1] = complex(-3.3, 7.9);
   *  multicompo->put("myComplArray", myComplexPtr, 2);
   * 
* @param key key identification of the block in the dictionary * @param myArray complex array stored as ComplexPtr object. * @param myLength number of components in complex array. */ void put(const std::string key, ComplexPtr myArray, const int_32 myLength); /** Store a complex array in a list-type Clcm object. This method is not * available for file-type Clcm objects. * @param iset index of the complex array in the list. The first list element * is stored at index 0. * @param myArray complex array stored as ComplexPtr object. * @param myLength number of components in complex array. */ void put(const int_32 iset, ComplexPtr myArray, const int_32 myLength); /** Store a daughter Clcm object in a dictionary-type Clcm object. This method is not * available for file-type Clcm objects. * @param key key identification of the block in the dictionary * @param myClcm daughter Clcm object. */ void put(const std::string key, ClcmPtr myClcm); /** Store a daughter Clcm object in a list-type Clcm object. This method is not * available for file-type Clcm objects. * @param iset index of the complex array in the list. The first list element * is stored at index 0. * @param myClcm daughter Clcm object. */ void put(const int_32 iset, ClcmPtr myClcm); /** Extract the LCM structure. * @return ANSI C pointer of the embedded LCM structure. */ lcm *extract(); private: std::vector *global_list; // container for the global references lcm *addr; // address of the LCM object Clcm *root; // address of Clcm root object std::ofstream aFile; // embedded file if type >= 3 int_32 lrda; // used with direct access files only std::string name; // object name std::string path; // path to access the Clcm file to import std::string nammy; // directory name inside LCM object bool empty; // empty flag int_32 ilong; // -1 (dictionary) or list length int_32 objtype; // type of the object =1: LCM; =2: XSM; =3: binary Fortran file // =4: ASCII Fortran file; =5: direct access Fortran file int_32 access; // =0: closed object; =1: object in read/write mode // =2: object in read-only mode int_32 version; // original ganlib version of object bool untoutched; // brand new object flag bool isroot; // true if addr is pointing on the root object }; // class Clcm std::ostream & operator<<(std::ostream &, ClcmPtr); } // namespace ganlib #endif