/** * @file * * @copyright * @verbatim Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved. This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. @endverbatim */ #ifndef DDL_IMPORTER_H_INCLUDED #define DDL_IMPORTER_H_INCLUDED #include "ddl_common.h" #include "ddlfactorymethod_intf.h" #include "ddlvisitor_intf.h" #include "ddlcontainer.h" namespace ddl { class DDLDescription; /** * \enum ImporterMsgSeverity * enumeration type for message severity */ typedef enum { importer_info, importer_warning, importer_error } ImporterMsgSeverity; /** * \struct ImporterMsg * error description structure type */ typedef struct { std::string desc; //!< string of the message ImporterMsgSeverity severity; //!< enumeration type for message severity } ImporterMsg; /** * Container for error descriptions */ typedef std::list ImporterMsgList; /** * Concrete Factory Method for building up a DDL from a XML file. */ class DDLImporter : public IDDLFactoryMethod { public: /** * Default CTOR * @param[in] basic_check Perform basic checks during Create* (unique element names etc.). * For a full check use DDLInspector. * @param[in] sorted Sorts all DDL items by name for better performance. */ DDLImporter(bool basic_check = true, bool sorted = true); /** * CTOR with file name/path * @param[in] file - Path to file to use * @param[in] basic_check Perform basic checks during Create* (unique element names etc.). * For a full check use DDLInspector. * @param[in] sorted Sorts all DDL items by name for better performance. */ DDLImporter(const a_util::filesystem::Path& file, bool basic_check = true, bool sorted = true); /** * CTOR with file name/path * @param[in] file - Path to file to use * @param[in] basic_check Perform basic checks during Create* (unique element names etc.). * For a full check use DDLInspector. * @param[in] sorted Sorts all DDL items by name for better performance. */ DDLImporter(const char* file, bool basic_check = true, bool sorted = true); /** * CTOR with creation level. * @param[in] creation_level - Creation level * @param[in] basic_check Perform basic checks during Create* (unique element names etc.). * For a full check use DDLInspector. * @param[in] sorted Sorts all DDL items by name for better performance. */ DDLImporter(int creation_level, bool basic_check = true, bool sorted = true); /// Default copy constructor DDLImporter(const DDLImporter&) = default; /** * Assignment operator (either copies or moves) * @param[in] other DDLImporter object to copy from * @return @c *this */ DDLImporter& operator=(DDLImporter other); /** * Move CTOR * @param[in,out] other DDLImporter object to move from - empty but valid when finished */ DDLImporter(DDLImporter&& other); /** * Add swap functionality, also enabling the copy-swap-idiom * @param[in,out] lhs Left-hand side ddl type * @param[in,out] rhs Right-hand side ddl type */ friend void swap(DDLImporter& lhs, DDLImporter& rhs) noexcept; public: // implements IDDLFactoryMethod virtual ~DDLImporter(); DDLDescription * getDDL() const; /** * @copydoc IDDLFactoryMethod::createNew(double) * @remarks If an error occurs, a list of detailed error descriptions * can be obtained using \c GetAllErrors(). */ a_util::result::Result createNew(const DDLVersion& version = DDLVersion::ddl_version_invalid); void destroyDDL(); a_util::result::Result buildHeader(); a_util::result::Result buildUnits(); a_util::result::Result buildDatatypes(); a_util::result::Result buildStructs(); a_util::result::Result buildStreams(); a_util::result::Result buildEnums(); a_util::result::Result buildStreamMetaTypes(); public: /** * Static method to destroy the given DDL hierarchy. * @param [in] ddl - Pointer to the DDL hierarchy which should be destroyed. * * @return void */ static void destroyDDL(DDLDescription *ddl); /** * Setter for the creation level. * @param[in] level - Creation level to use * * @return void */ void setCreationLevel(int const level = 1); /** * Setter for the validation mode. * @param[in] full_check - Validation mode to use. * Set true for full description check. * Set false for description check until first error. * * @return void */ void setFullCheckDescriptionMode(bool full_check = false); /** * Setter to enable disable the merge of DDL defaults (units, datattypes, etc.) * @param [in] merge_defaults See description * @return void */ void setMergeDefaults(bool merge_defaults = true); /** * Setter to switch from prefereing entities from the reference DDL, to using the reference * enties only when there is no "local" aquivalent. * Mind that reference entities are not cloned but only referenced. * They are also not included into the containers. * @param [in] prefere_reference See description * @return void */ void setPreferReferenceEntities(bool prefere_reference = true); /** * Method to create a partial DDL (e.g. streams only). * @param[in] ref_ddl - Reference DDL object to be used for resolving * matters * @param[in] version The version the newly created description will have. Set 0 for * newst version. * @retval ERR_POINTER Null-pointer committed * @retval ERR_NOT_INITIALIZED Not yet initialized (see setter methods * in concrete classes, e.g. \c DDLImporter::setFile()) * @retval ERR_UNKNOWN_FORMAT Expected XML hierarchy not found * @retval ERR_NO_CLASS Cross reference not resolvable (e.g. refUnit) * @retval ERR_UNKNOWN Cross reference has not been resolved */ a_util::result::Result createPartial(const DDLDescription* ref_ddl, const DDLVersion& version); /** * Setter for the source file. * @param[in] file - Path to file to use * @retval ERR_OPEN_FAILED Reading process failed * @retval ERR_UNEXPECTED Invalid XML tag */ a_util::result::Result setFile(const a_util::filesystem::Path& file); /** * Setter for a XML string containing the DDL to import. * @param[in] xml - String containing the DDL * @retval ERR_UNEXPECTED Invalid XML tag */ a_util::result::Result setXML(const std::string& xml); /** * Getter for the description of the last error. * @return the error description */ std::string getErrorDesc() const; /** * Getter for the most recent error description. * @return The error description or \c a_util::strings::empty_string if there was none. * @remarks This method indeed returns the last \b error message * (message with severity \c importer_error). */ std::string getLastErrorDesc() const; /** * Getter for all detected errors. * @return A list of all detected errors. */ ImporterMsgList getAllMessages() const; /** * Method to log all messages which have at least the given severity * to console. * @param[in] least_severity - Minimum severity level (optional) * * @return void */ void printAllMessages(ImporterMsgSeverity least_severity = importer_info); private: // methods /** * Creates a baseunit object from the given DOMElement. * @param[out] new_bu - Pointer to pointer to the newly created * baseunit object * @param[in] bu_element - The DOMElement with the information * @retval ERR_UNKNOWN_FORMAT Expected XML hierarchy not found * @retval ERR_NO_CLASS Cross reference not resolvable */ a_util::result::Result buildSingleBaseunit(DDLBaseunit ** new_bu, const a_util::xml::DOMElement& bu_element); /** * Creates a prefix object from the given DOMElement. * @param[out] new_prefix - Pointer to pointer to the newly created * prefix object * @param[in] prefix_element - The DOMElement with the information * @retval ERR_UNKNOWN_FORMAT Expected XML hierarchy not found * @retval ERR_NO_CLASS Cross reference not resolvable */ a_util::result::Result buildSinglePrefix(DDLPrefix ** new_prefix, const a_util::xml::DOMElement& prefix_element); /** * Creates a unit object from the given DOMElement. * @param[out] new_unit - Pointer to pointer to the newly created * unit object * @param[in] unit_element - The DOMElement with the information * @retval ERR_UNKNOWN_FORMAT Expected XML hierarchy not found * @retval ERR_NO_CLASS Cross reference not resolvable */ a_util::result::Result buildSingleUnit(DDLUnit ** new_unit, const a_util::xml::DOMElement& unit_element); /** * Creates a datatype object from the given DOMElement. * @param[out] new_datatype - Pointer to pointer to the newly * created datatype object * @param[in] dt_element -T he DOMElement with the information * @retval ERR_UNKNOWN_FORMAT Expected XML hierarchy not found * @retval ERR_NO_CLASS Cross reference not resolvable (e.g. unit) */ a_util::result::Result buildSingleDatatype(DDLDataType ** new_datatype, const a_util::xml::DOMElement& dt_element); /** * Creates an enum object from the given DOMElement. * @param[out] new_enum - Pointer to pointer to the newly * created enum object * @param[in] oEnumElement - The DOMElement with the information * @retval ERR_UNKNOWN_FORMAT Expected XML hierarchy not found * @retval ERR_NO_CLASS Cross reference not resolvable (e.g. unit) */ a_util::result::Result buildSingleEnum(DDLEnum** new_enum, const a_util::xml::DOMElement& enum_element); /** * Creates a struct object from the given DOMElement. * @param[out] new_struct - Pointer to pointer to the newly created * struct object * @param[in] struct_element - The DOMElement with the information * @retval ERR_UNKNOWN_FORMAT Expected XML hierarchy not found * @retval ERR_NO_CLASS Cross reference not resolvable (e.g. datatype) * @retval ERR_UNKNOWN Not all firstly unknown structs have been * resolved */ a_util::result::Result buildSingleStruct(DDLComplex ** new_struct, const a_util::xml::DOMElement& struct_element); /** * Creates a DDL stream object from the given DOMElement. * @param[out] new_stream - Pointer to pointer to the newly created * stream object * @param[in] stream_element - The DOMElement with the information * @retval ERR_UNKNOWN_FORMAT Expected XML hierarchy not found * @retval ERR_NO_CLASS Cross reference not resolvable (e.g. struct) */ a_util::result::Result buildSingleStream(DDLStream ** new_stream, a_util::xml::DOMElement stream_element); /** * Creates a DDL stream object from the given DOMElement. * @param[out] stream_meta_type_element * @param[in] stream_meta_types * @retval ERR_UNKNOWN_FORMAT Expected XML hierarchy not found * @retval ERR_NO_CLASS Cross reference not resolvable (e.g. struct) */ a_util::result::Result buildSingleStreamMetaType(const a_util::xml::DOMElement& stream_meta_type_element, DDLStreamMetaTypeVec& stream_meta_types); /** * Helper method to create a message and save it in the appropriate * container. * @param[in] msg - Message text * @param[in] severity - Message severity * @return void */ void pushMessage(const std::string& msg, ImporterMsgSeverity severity); /** * Helper method to find specific elements inside the given first_data by Name. * If not found there have a look in second_data. * @tparam T - Representation object type (e.g. DDLDataType) * @param[in] name - Name of the element to find * @param[in] first_data - Vector of representation objects to * search through * @param[in] second_data - second Vector of representation objects to * search through * @return pointer to the found element or \c NULL if not found */ template T* tryToFind(const std::string& name, DDLContainer& first_data, DDLContainer& second_data); private: // members a_util::xml::DOM _dom; DDLDescription *_ddl_desc; const DDLDescription *_current_ref_ddl; DDLUnitVec _unknown_units; DDLComplexVec _unknown_structs; DDLStreamMetaTypeVec _unknown_stream_meta_types; bool _init_flag; int _creation_level; bool _full_check; ImporterMsgList _errors; bool _basic_check; bool _merge_defaults; bool _sorted; bool _prefere_reference; }; } // namespace ddl #endif // DDL_IMPORTER_H_INCLUDED