LCOV - code coverage report
Current view: top level - nntrainer/utils - ini_wrapper.h (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 92.1 % 38 35
Test Date: 2025-12-14 20:38:17 Functions: 100.0 % 12 12

            Line data    Source code
       1              : // SPDX-License-Identifier: Apache-2.0
       2              : /**
       3              :  * Copyright (C) 2021 Jihoon Lee <jhoon.it.lee@samsung.com>
       4              :  *
       5              :  * @file ini_wrapper.h
       6              :  * @date 08 April 2021
       7              :  * @brief NNTrainer Ini Wrapper helps to save ini
       8              :  * @note this is to be used with ini_interpreter
       9              :  * @see https://github.com/nnstreamer/nntrainer
      10              :  * @author Jihoon Lee <jhoon.it.lee@samsung.com>
      11              :  * @bug No known bugs except for NYI items
      12              :  */
      13              : #ifndef __INI_WRAPPER_H__
      14              : #define __INI_WRAPPER_H__
      15              : 
      16              : #include <cstring>
      17              : #include <fstream>
      18              : #include <iosfwd>
      19              : #include <map>
      20              : #include <string>
      21              : #include <vector>
      22              : 
      23              : #include <node_exporter.h>
      24              : 
      25              : namespace nntrainer {
      26              : 
      27              : /**
      28              :  * @brief IniSection class that maps to one ini section
      29              :  * @todo consider API style setEntry function
      30              :  *
      31              :  */
      32            0 : class IniSection {
      33              : 
      34              : public:
      35              :   /**
      36              :    * @brief Construct a new Ini Section object
      37              :    *
      38              :    * @param name section name
      39              :    */
      40              :   IniSection(const std::string &name);
      41              : 
      42              :   /**
      43              :    * @brief Construct a new Ini Section object
      44              :    *
      45              :    * @param section_name section name
      46              :    * @param entry_str entry representing string (separated by `|`)
      47              :    */
      48              :   IniSection(const std::string &section_name, const std::string &entry_str);
      49              : 
      50              :   /**
      51              :    * @brief Copy Construct a new Ini Section object
      52              :    * @note this function copies entry from @a from and overwrite entry and
      53              :    * section_name
      54              :    *
      55              :    * @param from Ini Section to copy from
      56              :    * @param section_name section name to override, if empty, section name is not
      57              :    * updated
      58              :    * @param entry_str entry string to override the given section name
      59              :    */
      60              :   IniSection(IniSection &from, const std::string &section_name,
      61              :              const std::string &entry_str);
      62              : 
      63              :   /**
      64              :    * @brief Construct a new Ini Section object
      65              :    *
      66              :    * @param from Ini Section to copy from
      67              :    * @param entry_str entry string to override the given section name
      68              :    */
      69              :   IniSection(IniSection &from, const std::string &entry_str) :
      70              :     IniSection(from, "", entry_str) {}
      71              : 
      72              :   /**
      73              :    * @brief Default constructor for the Ini Section object
      74              :    *
      75              :    */
      76              :   IniSection() : section_name(""), entry{} {};
      77              : 
      78              :   /**
      79              :    * @brief Construct a new Ini Section object from which implements
      80              :    * object::exportTo
      81              :    *
      82              :    * @tparam Exportable object with member object::exportTo
      83              :    * @param section_name section name
      84              :    * @param exportable exportable object
      85              :    * @return IniSection created section
      86              :    */
      87              :   template <typename Exportable>
      88         2335 :   static IniSection FromExportable(const std::string &section_name,
      89              :                                    const Exportable &exportable) {
      90         2335 :     IniSection s(section_name);
      91         2335 :     Exporter e;
      92         2335 :     exportable.exportTo(e, ml::train::ExportMethods::METHOD_STRINGVECTOR);
      93         2335 :     const auto key_val_pairs =
      94              :       e.getResult<ml::train::ExportMethods::METHOD_STRINGVECTOR>();
      95              : 
      96         2335 :     if (!key_val_pairs) {
      97            0 :       throw std::invalid_argument("returned pairs are nullptr!");
      98              :     }
      99              : 
     100        23180 :     for (const auto &pair : *key_val_pairs) {
     101        20845 :       s.setEntry(pair.first, pair.second);
     102              :     }
     103         2335 :     return s;
     104         2335 :   }
     105              : 
     106              :   /**
     107              :    * @brief Default destructor for the Ini Section object
     108              :    *
     109              :    */
     110        35355 :   ~IniSection() = default;
     111              : 
     112              :   /**
     113              :    * @brief +=operator from IniSection
     114              :    *
     115              :    * @param rhs operand to add
     116              :    * @return IniSection& this
     117              :    */
     118              :   IniSection &operator+=(const IniSection &rhs) {
     119           78 :     setEntry(rhs.entry);
     120              :     return *this;
     121              :   }
     122              : 
     123              :   /**
     124              :    * @brief + operator from IniSection
     125              :    *
     126              :    * @param rhs operand to add
     127              :    * @return IniSection new Inisection
     128              :    */
     129           72 :   IniSection operator+(const IniSection &rhs) const {
     130          216 :     return IniSection(*this) += rhs;
     131              :   }
     132              : 
     133              :   /**
     134              :    * @brief += operator from string
     135              :    *
     136              :    * @param s string representation to add
     137              :    * @return IniSection& this
     138              :    */
     139              :   IniSection &operator+=(const std::string &s) {
     140         1219 :     setEntry(s);
     141              :     return *this;
     142              :   }
     143              : 
     144              :   /**
     145              :    * @brief + operator from string
     146              :    *
     147              :    * @param s string representation to add
     148              :    * @return IniSection Newly created section
     149              :    */
     150         3657 :   IniSection operator+(const std::string &s) { return IniSection(*this) += s; }
     151              : 
     152              :   /**
     153              :    * @brief equal operator between ini section
     154              :    *
     155              :    * @param rhs ini section to compare
     156              :    * @retval true two inisections are equal
     157              :    * @retval false two ini sections are not equal
     158              :    */
     159              :   bool operator==(const IniSection &rhs) const {
     160              :     return section_name == rhs.section_name && entry == rhs.entry;
     161              :   }
     162              : 
     163              :   /**
     164              :    * @brief  not equal operator between ini section
     165              :    *
     166              :    * @param rhs ini section to compare
     167              :    * @retval true two inisections are not equal
     168              :    * @retval false two inisections are equal
     169              :    */
     170              :   bool operator!=(const IniSection &rhs) const { return !operator==(rhs); }
     171              : 
     172              :   /**
     173              :    * @brief print out a section
     174              :    *
     175              :    * @param out ostream to print
     176              :    */
     177              :   void print(std::ostream &out) const;
     178              : 
     179              :   /**
     180              :    * @brief Get the Name object
     181              :    *
     182              :    * @return std::string section name
     183              :    */
     184           10 :   std::string getName() const { return section_name; }
     185              : 
     186              :   /**
     187              :    * @brief Set the Entry object by key and value
     188              :    *
     189              :    * @param key key to update
     190              :    * @param value value to be added
     191              :    */
     192              :   void setEntry(const std::string &key, const std::string &value);
     193              : 
     194              : private:
     195              :   /**
     196              :    * @brief Set the Entry
     197              :    *
     198              :    * @param entry set entry from a given map
     199              :    */
     200              :   void setEntry(const std::map<std::string, std::string> &entry);
     201              : 
     202              :   /**
     203              :    * @brief set entry from the string representation
     204              :    *
     205              :    * @param entry_str setEntry as "Type = neuralnetwork | decayrate = 0.96 |
     206              :    * -epochs = 1" will delete epochs, and overwrite type and decayrate
     207              :    */
     208              :   void setEntry(const std::string &entry_str);
     209              : 
     210              :   std::string section_name; /**< section name of the ini section */
     211              : 
     212              :   /// @note if ini_wrapper needs to be optimized, change this to unordered_map
     213              :   std::map<std::string, std::string>
     214              :     entry; /**< entry information that this ini contains */
     215              : 
     216              :   /**
     217              :    * @brief <<operator of a section
     218              :    *
     219              :    * @param os ostream
     220              :    * @param section section to print
     221              :    * @return std::ostream& ostream
     222              :    */
     223              :   friend std::ostream &operator<<(std::ostream &os, const IniSection &section) {
     224              :     return os << section.section_name;
     225              :   }
     226              : };
     227              : 
     228              : /**
     229              :  * @brief IniWrapper using IniSections
     230              :  *
     231              :  */
     232         2743 : class IniWrapper {
     233              : public:
     234              :   using Sections = std::vector<IniSection>;
     235              : 
     236              :   /**
     237              :    * @brief Construct a new Ini Test Wrapper object
     238              :    *
     239              :    */
     240              :   IniWrapper() = default;
     241              : 
     242              :   /**
     243              :    * @brief Construct a new Ini Test Wrapper object
     244              :    *
     245              :    * @param name_ name of the ini without `.ini` extension
     246              :    * @param sections_ sections that should go into ini
     247              :    */
     248          866 :   IniWrapper(const std::string &name_, const Sections &sections_ = {}) :
     249          866 :     name(name_),
     250          866 :     sections(sections_){};
     251              : 
     252              :   /**
     253              :    * @brief ini operator== to check if IniWrapper is equal
     254              :    *
     255              :    * @param rhs IniWrapper to compare
     256              :    * @retval true true if ini is equal (deeply)
     257              :    * @retval false false if ini is not equal
     258              :    */
     259              :   bool operator==(const IniWrapper &rhs) const {
     260              :     return name == rhs.name && sections == rhs.sections;
     261              :   }
     262              : 
     263              :   /**
     264              :    * @brief ini operator!= to check if IniWrapper is not equal
     265              :    *
     266              :    * @param rhs IniWrapper to compare
     267              :    * @retval true if not equal
     268              :    * @retval false if equal
     269              :    */
     270              :   bool operator!=(const IniWrapper &rhs) const { return !operator==(rhs); }
     271              : 
     272              :   /**
     273              :    * @brief update sections if section is empty, else update section by section
     274              :    * by key
     275              :    *
     276              :    * @param[in] ini IniWrapper
     277              :    * @return IniWrapper& this
     278              :    */
     279           11 :   IniWrapper &operator+=(const IniWrapper &ini) {
     280           11 :     if (sections.empty()) {
     281           11 :       sections = ini.sections;
     282              :     } else {
     283            0 :       updateSections(ini.sections);
     284              :     }
     285              : 
     286           11 :     return *this;
     287              :   }
     288              : 
     289              :   /**
     290              :    * @brief update sections if section is empty, else update section by section
     291              :    * by key
     292              :    *
     293              :    * @param[in] rhs IniWrapper
     294              :    * @return IniWrapper& a new instance
     295              :    */
     296           11 :   IniWrapper operator+(const IniWrapper &rhs) const {
     297           22 :     return IniWrapper(*this) += rhs;
     298              :   }
     299              : 
     300              :   /**
     301              :    * @brief update a single section using operator+=
     302              :    *
     303              :    * @param string format of `sectionkey / propkey=val | propkey=val| ..`
     304              :    * @return IniWrapper& ini wrapper
     305              :    */
     306              :   IniWrapper &operator+=(const std::string &s) {
     307            6 :     updateSection(s);
     308              :     return *this;
     309              :   }
     310              : 
     311              :   /**
     312              :    * @brief update a single section using operator+=
     313              :    *
     314              :    * @param string format of `sectionkey / propkey=val | propkey=val| ..`
     315              :    * @return IniWrapper& ini wrapper
     316              :    */
     317              :   IniWrapper &operator+=(const IniSection &section_) {
     318           10 :     sections.push_back(section_);
     319              :     return *this;
     320              :   }
     321              : 
     322              :   /**
     323              :    * @brief update a single section using operator +
     324              :    *
     325              :    * @param rhs string representatioin to merge
     326              :    * @return IniWrapper ini wrapper
     327              :    */
     328            6 :   IniWrapper operator+(const std::string &rhs) const {
     329           18 :     return IniWrapper(*this) += rhs;
     330              :   }
     331              : 
     332              :   /**
     333              :    * @brief update a single section using operator +
     334              :    *
     335              :    * @param rhs string representatioin to merge
     336              :    * @return IniWrapper ini wrapper
     337              :    */
     338           10 :   IniWrapper operator+(const IniSection &section_) const {
     339           30 :     return IniWrapper(*this) += section_;
     340              :   }
     341              : 
     342              :   /**
     343              :    * @brief Get the Ini Name object
     344              :    *
     345              :    * @return std::string ini name with extension appended
     346              :    */
     347         1280 :   std::string getIniName() const { return name + ".ini"; }
     348              : 
     349              :   /**
     350              :    * @brief Get the Name
     351              :    *
     352              :    * @return std::string name
     353              :    */
     354          132 :   std::string getName() const { return name; }
     355              : 
     356              :   /**
     357              :    * @brief save ini to a file, (getIniName() is used to save)
     358              :    */
     359              :   void save_ini() const;
     360              : 
     361              :   /**
     362              :    * @brief save ini by ini_name
     363              :    *
     364              :    * @param ini_name ini name to svae
     365              :    */
     366              :   void save_ini(const std::string &ini_name) const;
     367              : 
     368              :   /**
     369              :    * @brief erase ini
     370              :    *
     371              :    */
     372              :   void erase_ini() const noexcept;
     373              : 
     374              :   /**
     375              :    * @brief operator<< to print information to outstream
     376              :    *
     377              :    * @param os outstream
     378              :    * @param ini ini wrapper
     379              :    * @return std::ostream& outstream
     380              :    */
     381              :   friend std::ostream &operator<<(std::ostream &os, const IniWrapper &ini) {
     382              :     return os << ini.name;
     383              :   }
     384              : 
     385              : private:
     386              :   /**
     387              :    * @brief update a section from a formatted string, `sectionkey / propkey=val
     388              :    * | propkey=val`
     389              :    * @note add containered version of this, something like std::pair
     390              :    * @param string_representation "model/optimizer=SGD | ..."
     391              :    */
     392              :   void updateSection(const std::string &string_representation);
     393              : 
     394              :   /**
     395              :    * @brief update Section that matches section key of @a sections
     396              :    *
     397              :    * @param section section
     398              :    */
     399              :   void updateSection(const IniSection &section);
     400              : 
     401              :   /**
     402              :    * @brief update sections with following rule
     403              :    * if there is a section key, update entry of the section else throw
     404              :    * std::invalid_argument
     405              :    * @param sections sections to update
     406              :    */
     407              :   void updateSections(const Sections &sections_);
     408              : 
     409              :   std::string name;  /**< name of ini */
     410              :   Sections sections; /**< sections of ini */
     411              : };
     412              : 
     413              : } // namespace nntrainer
     414              : 
     415              : #endif // __INI_WRAPPER_H__
        

Generated by: LCOV version 2.0-1