#include "platform/settings.hpp" #include "platform/location.hpp" #include "platform/measurement_utils.hpp" #include "platform/platform.hpp" #include "defines.hpp" #include "coding/file_reader.hpp" #include "coding/file_writer.hpp" #include "coding/reader_streambuf.hpp" #include "coding/transliteration.hpp" #include "geometry/any_rect2d.hpp" #include "geometry/rect2d.hpp" #include "base/logging.hpp" #include #include #include using namespace std; namespace settings { char const * kLocationStateMode = "LastLocationStateMode"; char const * kMeasurementUnits = "Units"; StringStorage::StringStorage() : StringStorageBase(GetPlatform().SettingsPathForFile(SETTINGS_FILE_NAME)) {} StringStorage & StringStorage::Instance() { static StringStorage inst; return inst; } //////////////////////////////////////////////////////////////////////////////////////////// template <> string ToString(string const & str) { return str; } template <> bool FromString(string const & strIn, string & strOut) { strOut = strIn; return true; } namespace impl { template bool FromStringArray(string const & s, T(&arr)[N]) { istringstream in(s); size_t count = 0; while (count < N && in >> arr[count]) { if (!isfinite(arr[count])) return false; ++count; } return (!in.fail() && count == N); } } // namespace impl template <> string ToString(m2::AnyRectD const & rect) { ostringstream out; out.precision(12); m2::PointD glbZero(rect.GlobalZero()); out << glbZero.x << " " << glbZero.y << " "; out << rect.Angle().val() << " "; m2::RectD const & r = rect.GetLocalRect(); out << r.minX() << " " << r.minY() << " " << r.maxX() << " " << r.maxY(); return out.str(); } template <> bool FromString(string const & str, m2::AnyRectD & rect) { double val[7]; if (!impl::FromStringArray(str, val)) return false; // Will get an assertion in DEBUG and false return in RELEASE. m2::RectD const r(val[3], val[4], val[5], val[6]); if (!r.IsValid()) return false; rect = m2::AnyRectD(m2::PointD(val[0], val[1]), ang::AngleD(val[2]), r); return true; } template <> string ToString(m2::RectD const & rect) { ostringstream stream; stream.precision(12); stream << rect.minX() << " " << rect.minY() << " " << rect.maxX() << " " << rect.maxY(); return stream.str(); } template <> bool FromString(string const & str, m2::RectD & rect) { double val[4]; if (!impl::FromStringArray(str, val)) return false; // Will get an assertion in DEBUG and false return in RELEASE. rect = m2::RectD(val[0], val[1], val[2], val[3]); return rect.IsValid(); } template <> string ToString(bool const & v) { return v ? "true" : "false"; } template <> bool FromString(string const & str, bool & v) { if (str == "true") v = true; else if (str == "false") v = false; else return false; return true; } namespace impl { template string ToStringScalar(T const & v) { ostringstream stream; stream.precision(12); stream << v; return stream.str(); } template bool FromStringScalar(string const & str, T & v) { istringstream stream(str); if (stream) { stream >> v; return !stream.fail(); } else return false; } } // namespace impl template <> string ToString(double const & v) { return impl::ToStringScalar(v); } template <> bool FromString(string const & str, double & v) { return impl::FromStringScalar(str, v); } template <> string ToString(int32_t const & v) { return impl::ToStringScalar(v); } template <> bool FromString(string const & str, int32_t & v) { return impl::FromStringScalar(str, v); } template <> string ToString(int64_t const & v) { return impl::ToStringScalar(v); } template <> bool FromString(string const & str, int64_t & v) { return impl::FromStringScalar(str, v); } template <> string ToString(uint32_t const & v) { return impl::ToStringScalar(v); } template <> string ToString(uint64_t const & v) { return impl::ToStringScalar(v); } template <> bool FromString(string const & str, uint32_t & v) { return impl::FromStringScalar(str, v); } template <> bool FromString(string const & str, uint64_t & v) { return impl::FromStringScalar(str, v); } namespace impl { template string ToStringPair(TPair const & value) { ostringstream stream; stream.precision(12); stream << value.first << " " << value.second; return stream.str(); } template bool FromStringPair(string const & str, TPair & value) { istringstream stream(str); if (stream) { stream >> value.first; if (stream) { stream >> value.second; return !stream.fail(); } } return false; } } // namespace impl typedef pair IPairT; typedef pair DPairT; template <> string ToString(IPairT const & v) { return impl::ToStringPair(v); } template <> bool FromString(string const & s, IPairT & v) { return impl::FromStringPair(s, v); } template <> string ToString(DPairT const & v) { return impl::ToStringPair(v); } template <> bool FromString(string const & s, DPairT & v) { return impl::FromStringPair(s, v); } template <> string ToString(measurement_utils::Units const & v) { switch (v) { // The value "Foot" is left here for compatibility with old settings.ini files. case measurement_utils::Units::Imperial: return "Foot"; case measurement_utils::Units::Metric: return "Metric"; } UNREACHABLE(); } template <> bool FromString(string const & s, measurement_utils::Units & v) { if (s == "Metric") v = measurement_utils::Units::Metric; else if (s == "Foot") v = measurement_utils::Units::Imperial; else return false; return true; } template <> string ToString(location::EMyPositionMode const & v) { switch (v) { case location::PendingPosition: return "PendingPosition"; case location::NotFollow: return "NotFollow"; case location::NotFollowNoPosition: return "NotFollowNoPosition"; case location::Follow: return "Follow"; case location::FollowAndRotate: return "FollowAndRotate"; default: return "Pending"; } } template <> bool FromString(string const & s, location::EMyPositionMode & v) { if (s == "PendingPosition") v = location::PendingPosition; else if (s == "NotFollow") v = location::NotFollow; else if (s == "NotFollowNoPosition") v = location::NotFollowNoPosition; else if (s == "Follow") v = location::Follow; else if (s == "FollowAndRotate") v = location::FollowAndRotate; else return false; return true; } template <> string ToString(Transliteration::Mode const & mode) { switch (mode) { case Transliteration::Mode::Enabled: return "Enabled"; case Transliteration::Mode::Disabled: return "Disabled"; } UNREACHABLE(); } template <> bool FromString(string const & s, Transliteration::Mode & mode) { if (s == "Enabled") mode = Transliteration::Mode::Enabled; else if (s == "Disabled") mode = Transliteration::Mode::Disabled; else return false; return true; } bool IsFirstLaunchForDate(int date) { constexpr char const * kFirstLaunchKey = "FirstLaunchOnDate"; int savedDate; if (!Get(kFirstLaunchKey, savedDate) || savedDate < date) { Set(kFirstLaunchKey, date); return true; } else return false; } } // namespace settings namespace marketing { Settings::Settings() : platform::StringStorageBase(GetPlatform().SettingsPathForFile(MARKETING_SETTINGS_FILE_NAME)) {} // static Settings & Settings::Instance() { static Settings instance; return instance; } } // namespace marketing