From bcc1e51097b0bfac30f2ffb0d81c5b8a7cfd874f Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 17 Jul 2018 23:27:50 +0200
Subject: [PATCH] StateFile: add struct StateFileConfig

---
 Makefile.am             |  1 +
 src/Main.cxx            | 22 ++++-----------------
 src/StateFile.cxx       | 14 +++++--------
 src/StateFile.hxx       |  9 ++++-----
 src/StateFileConfig.cxx | 44 +++++++++++++++++++++++++++++++++++++++++
 src/StateFileConfig.hxx | 44 +++++++++++++++++++++++++++++++++++++++++
 6 files changed, 102 insertions(+), 32 deletions(-)
 create mode 100644 src/StateFileConfig.cxx
 create mode 100644 src/StateFileConfig.hxx

diff --git a/Makefile.am b/Makefile.am
index 4c72e44b4..e04fbfc76 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -175,6 +175,7 @@ libmpd_a_SOURCES = \
 	src/SongPrint.cxx src/SongPrint.hxx \
 	src/SongSave.cxx src/SongSave.hxx \
 	src/StateFile.cxx src/StateFile.hxx \
+	src/StateFileConfig.cxx src/StateFileConfig.hxx \
 	src/Stats.cxx src/Stats.hxx \
 	src/TagPrint.cxx src/TagPrint.hxx \
 	src/TagSave.cxx src/TagSave.hxx \
diff --git a/src/Main.cxx b/src/Main.cxx
index 2932a0741..5c933c4f2 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -93,7 +93,6 @@
 #include "java/File.hxx"
 #include "android/Environment.hxx"
 #include "android/Context.hxx"
-#include "fs/StandardDirectory.hxx"
 #include "fs/FileSystem.hxx"
 #include "org_musicpd_Bridge.h"
 #endif
@@ -256,26 +255,13 @@ glue_sticker_init(const ConfigData &config)
 }
 
 static void
-glue_state_file_init(const ConfigData &config)
+glue_state_file_init(const ConfigData &raw_config)
 {
-	auto path_fs = config.GetPath(ConfigOption::STATE_FILE);
-	if (path_fs.IsNull()) {
-#ifdef ANDROID
-		const auto cache_dir = GetUserCacheDir();
-		if (cache_dir.IsNull())
-			return;
-
-		path_fs = cache_dir / Path::FromFS("state");
-#else
+	StateFileConfig config(raw_config);
+	if (!config.IsEnabled())
 		return;
-#endif
-	}
 
-	const auto interval =
-		config.GetUnsigned(ConfigOption::STATE_FILE_INTERVAL,
-				   StateFile::DEFAULT_INTERVAL);
-
-	instance->state_file = new StateFile(std::move(path_fs), interval,
+	instance->state_file = new StateFile(std::move(config),
 					     instance->partitions.front(),
 					     instance->event_loop);
 	instance->state_file->Read();
diff --git a/src/StateFile.cxx b/src/StateFile.cxx
index 6443f8a66..14618bc6e 100644
--- a/src/StateFile.cxx
+++ b/src/StateFile.cxx
@@ -38,13 +38,9 @@
 
 static constexpr Domain state_file_domain("state_file");
 
-constexpr std::chrono::steady_clock::duration StateFile::DEFAULT_INTERVAL;
-
-StateFile::StateFile(AllocatedPath &&_path,
-		     std::chrono::steady_clock::duration _interval,
+StateFile::StateFile(StateFileConfig &&_config,
 		     Partition &_partition, EventLoop &_loop)
-	:path(std::move(_path)), path_utf8(path.ToUTF8()),
-	 interval(_interval),
+	:config(std::move(_config)), path_utf8(config.path.ToUTF8()),
 	 timer_event(_loop, BIND_THIS_METHOD(OnTimeout)),
 	 partition(_partition)
 {
@@ -103,7 +99,7 @@ StateFile::Write()
 		    "Saving state file %s", path_utf8.c_str());
 
 	try {
-		FileOutputStream fos(path);
+		FileOutputStream fos(config.path);
 		Write(fos);
 		fos.Commit();
 	} catch (const std::exception &e) {
@@ -120,7 +116,7 @@ try {
 
 	FormatDebug(state_file_domain, "Loading state file %s", path_utf8.c_str());
 
-	TextFile file(path);
+	TextFile file(config.path);
 
 #ifdef ENABLE_DATABASE
 	const SongLoader song_loader(partition.instance.database,
@@ -155,7 +151,7 @@ void
 StateFile::CheckModified()
 {
 	if (!timer_event.IsActive() && IsModified())
-		timer_event.Schedule(interval);
+		timer_event.Schedule(config.interval);
 }
 
 void
diff --git a/src/StateFile.hxx b/src/StateFile.hxx
index ed0f9fcef..de5b994d0 100644
--- a/src/StateFile.hxx
+++ b/src/StateFile.hxx
@@ -20,6 +20,7 @@
 #ifndef MPD_STATE_FILE_HXX
 #define MPD_STATE_FILE_HXX
 
+#include "StateFileConfig.hxx"
 #include "event/TimerEvent.hxx"
 #include "fs/AllocatedPath.hxx"
 #include "Compiler.h"
@@ -32,10 +33,10 @@ class OutputStream;
 class BufferedOutputStream;
 
 class StateFile final {
-	const AllocatedPath path;
+	const StateFileConfig config;
+
 	const std::string path_utf8;
 
-	const std::chrono::steady_clock::duration interval;
 	TimerEvent timer_event;
 
 	Partition &partition;
@@ -52,9 +53,7 @@ class StateFile final {
 #endif
 
 public:
-	static constexpr std::chrono::steady_clock::duration DEFAULT_INTERVAL = std::chrono::minutes(2);
-
-	StateFile(AllocatedPath &&path, std::chrono::steady_clock::duration interval,
+	StateFile(StateFileConfig &&_config,
 		  Partition &partition, EventLoop &loop);
 
 	void Read();
diff --git a/src/StateFileConfig.cxx b/src/StateFileConfig.cxx
new file mode 100644
index 000000000..4e6cc1067
--- /dev/null
+++ b/src/StateFileConfig.cxx
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2003-2018 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "StateFileConfig.hxx"
+#include "config/Data.hxx"
+
+#ifdef ANDROID
+#include "fs/StandardDirectory.hxx"
+#endif
+
+constexpr std::chrono::steady_clock::duration StateFileConfig::DEFAULT_INTERVAL;
+
+StateFileConfig::StateFileConfig(const ConfigData &config)
+	:path(config.GetPath(ConfigOption::STATE_FILE)),
+	 interval(config.GetUnsigned(ConfigOption::STATE_FILE_INTERVAL,
+				     DEFAULT_INTERVAL))
+{
+#ifdef ANDROID
+	if (path.IsNull()) {
+		const auto cache_dir = GetUserCacheDir();
+		if (cache_dir.IsNull())
+			return;
+
+		path = cache_dir / Path::FromFS("state");
+	}
+#endif
+}
diff --git a/src/StateFileConfig.hxx b/src/StateFileConfig.hxx
new file mode 100644
index 000000000..1faa20caf
--- /dev/null
+++ b/src/StateFileConfig.hxx
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2003-2018 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MPD_STATE_FILE_CONFIG_HXX
+#define MPD_STATE_FILE_CONFIG_HXX
+
+#include "check.h"
+#include "fs/AllocatedPath.hxx"
+
+#include <chrono>
+
+struct ConfigData;
+
+struct StateFileConfig {
+	static constexpr std::chrono::steady_clock::duration DEFAULT_INTERVAL = std::chrono::minutes(2);
+
+	AllocatedPath path;
+
+	std::chrono::steady_clock::duration interval;
+
+	explicit StateFileConfig(const ConfigData &config);
+
+	bool IsEnabled() const noexcept {
+		return !path.IsNull();
+	}
+};
+
+#endif