@@ -206,6 +206,9 @@ class INIReader {
206206 // about the parsing.
207207 INIReader (std::string filename);
208208
209+ // Construct INIReader and parse given filepath, unicode paths supported
210+ INIReader (const std::filesystem::path& filepath);
211+
209212 // Construct INIReader and parse given file. See ini.h for more info
210213 // about the parsing.
211214 INIReader (FILE* file);
@@ -240,20 +243,12 @@ class INIReader {
240243 const std::vector<T>& default_v) const ;
241244
242245 template <typename T = std::string>
243- void InsertEntry (const std::string& section, const std::string& name,
244- const T& v);
245-
246- template <typename T = std::string>
247- void InsertEntry (const std::string& section, const std::string& name,
248- const std::vector<T>& vs);
249-
250- template <typename T = std::string>
251- void UpdateEntry (const std::string& section, const std::string& name,
252- const T& v);
246+ void Set (const std::string& section, const std::string& name,
247+ const T& v);
253248
254249 template <typename T = std::string>
255- void UpdateEntry (const std::string& section, const std::string& name,
256- const std::vector<T>& vs);
250+ void Set (const std::string& section, const std::string& name,
251+ const std::vector<T>& vs);
257252
258253 protected:
259254 int _error;
@@ -290,6 +285,20 @@ inline INIReader::INIReader(std::string filename) {
290285 ParseError ();
291286}
292287
288+ /* *
289+ * @brief Construct an INIReader object from a file path
290+ * @param filepath The path of the INI file to parse
291+ * @throws std::runtime_error if there is an error parsing the INI file
292+ */
293+ inline INIReader::INIReader (const std::filesystem::path& filepath) {
294+ const std::wstring path_str = filepath.wstring ();
295+ FILE* iniFile;
296+ errno_t result = _wfopen_s (&iniFile, path_str.c_str (), L" r" );
297+ _error = ini_parse_file (iniFile, ValueHandler, this );
298+ ParseError ();
299+ fclose (iniFile);
300+ }
301+
293302/* *
294303 * @brief Construct an INIReader object from a file pointer
295304 * @param file A pointer to the INI file to parse
@@ -461,41 +470,6 @@ inline std::vector<T> INIReader::GetVector(
461470 };
462471}
463472
464- /* *
465- * @brief Insert a key-value pair into the INI file
466- * @param section The section name
467- * @param name The key name
468- * @param v The value to insert
469- * @throws std::runtime_error if the key already exists in the section
470- */
471- template <typename T>
472- inline void INIReader::InsertEntry (const std::string& section,
473- const std::string& name, const T& v) {
474- if (_values[section][name].size () > 0 ) {
475- throw std::runtime_error (" duplicate key '" + std::string (name) +
476- " ' in section '" + section + " '." );
477- }
478- _values[section][name] = V2String (v);
479- }
480-
481- /* *
482- * @brief Insert a vector of values into the INI file
483- * @param section The section name
484- * @param name The key name
485- * @param vs The vector of values to insert
486- * @throws std::runtime_error if the key already exists in the section
487- */
488- template <typename T>
489- inline void INIReader::InsertEntry (const std::string& section,
490- const std::string& name,
491- const std::vector<T>& vs) {
492- if (_values[section][name].size () > 0 ) {
493- throw std::runtime_error (" duplicate key '" + std::string (name) +
494- " ' in section '" + section + " '." );
495- }
496- _values[section][name] = Vec2String (vs);
497- }
498-
499473/* *
500474 * @brief Update a key-value pair in the INI file
501475 * @param section The section name
@@ -504,12 +478,8 @@ inline void INIReader::InsertEntry(const std::string& section,
504478 * @throws std::runtime_error if the key does not exist in the section
505479 */
506480template <typename T>
507- inline void INIReader::UpdateEntry (const std::string& section,
508- const std::string& name, const T& v) {
509- if (!_values[section][name].size ()) {
510- throw std::runtime_error (" key '" + std::string (name) +
511- " ' not exist in section '" + section + " '." );
512- }
481+ inline void INIReader::Set (const std::string& section,
482+ const std::string& name, const T& v) {
513483 _values[section][name] = V2String (v);
514484}
515485
@@ -521,9 +491,9 @@ inline void INIReader::UpdateEntry(const std::string& section,
521491 * @throws std::runtime_error if the key does not exist in the section
522492 */
523493template <typename T>
524- inline void INIReader::UpdateEntry (const std::string& section,
525- const std::string& name,
526- const std::vector<T>& vs) {
494+ inline void INIReader::Set (const std::string& section,
495+ const std::string& name,
496+ const std::vector<T>& vs) {
527497 if (!_values[section][name].size ()) {
528498 throw std::runtime_error (" key '" + std::string (name) +
529499 " ' not exist in section '" + section + " '." );
@@ -604,15 +574,12 @@ class INIWriter {
604574 * @throws std::runtime_error if the output file already exists or cannot be
605575 * opened
606576 */
607- inline static void write (const std::string & filepath,
577+ inline static void write (const std::filesystem::path & filepath,
608578 const INIReader& reader) {
609- if (struct stat buf; stat (filepath.c_str (), &buf) == 0 ) {
610- throw std::runtime_error (" file: " + filepath + " already exist." );
611- }
612579 std::ofstream out;
613580 out.open (filepath);
614581 if (!out.is_open ()) {
615- throw std::runtime_error (" cannot open output file: " + filepath);
582+ throw std::runtime_error (" cannot open output file: " + filepath. string () );
616583 }
617584 for (const auto & section : reader.Sections ()) {
618585 out << " [" << section << " ]\n " ;
0 commit comments