config_parser: Add function for writing files

This will be used by the configuration writers shortly.

Change-Id: I6e72b181e365e34808c8e5e4790c446124dc13a3
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/config_parser.cpp b/src/config_parser.cpp
index cd9960d..599908e 100644
--- a/src/config_parser.cpp
+++ b/src/config_parser.cpp
@@ -7,7 +7,9 @@
 #include <iterator>
 #include <stdexcept>
 #include <stdplus/exception.hpp>
+#include <stdplus/fd/atomic.hpp>
 #include <stdplus/fd/create.hpp>
+#include <stdplus/fd/fmt.hpp>
 #include <stdplus/fd/line.hpp>
 #include <string>
 #include <utility>
@@ -275,6 +277,39 @@
     this->warnings = std::move(parse.warnings);
 }
 
+static void writeFileInt(const SectionMap& map, const fs::path& filename)
+{
+    stdplus::fd::AtomicWriter writer(filename, 0644);
+    stdplus::fd::FormatBuffer out(writer);
+    for (const auto& [section, maps] : map)
+    {
+        for (const auto& map : maps)
+        {
+            out.append(FMT_COMPILE("[{}]\n"), section.get());
+            for (const auto& [key, vals] : map)
+            {
+                for (const auto& val : vals)
+                {
+                    out.append(FMT_COMPILE("{}={}\n"), key.get(), val.get());
+                }
+            }
+        }
+    }
+    out.flush();
+    writer.commit();
+}
+
+void Parser::writeFile() const
+{
+    writeFileInt(map, filename);
+}
+
+void Parser::writeFile(const fs::path& filename)
+{
+    writeFileInt(map, filename);
+    this->filename = filename;
+}
+
 } // namespace config
 } // namespace network
 } // namespace phosphor
diff --git a/src/config_parser.hpp b/src/config_parser.hpp
index 8ec693a..12ac417 100644
--- a/src/config_parser.hpp
+++ b/src/config_parser.hpp
@@ -190,6 +190,10 @@
      */
     void setFile(const fs::path& filename);
 
+    /** @brief Write the current config to a file */
+    void writeFile() const;
+    void writeFile(const fs::path& filename);
+
   private:
     fs::path filename;
     std::vector<std::string> warnings;
diff --git a/test/test_config_parser.cpp b/test/test_config_parser.cpp
index 0dd16af..3bb0897 100644
--- a/test/test_config_parser.cpp
+++ b/test/test_config_parser.cpp
@@ -160,6 +160,20 @@
     EXPECT_THAT(map.getValueStrings("Network", "nil"), ElementsAre());
 }
 
+TEST_F(TestConfigParser, WriteConfigFile)
+{
+    WriteSampleFile();
+    parser.setFile(filename);
+    EXPECT_EQ(4, parser.getWarnings().size());
+    ValidateSectionMap();
+
+    parser.writeFile();
+
+    parser.setFile(filename);
+    EXPECT_EQ(0, parser.getWarnings().size());
+    ValidateSectionMap();
+}
+
 TEST_F(TestConfigParser, Perf)
 {
     GTEST_SKIP();