]> git.stg.codes - stg.git/commitdiff
Fight Optional
authorMaksym Mamontov <madf@madf.info>
Sun, 24 Jul 2022 15:51:46 +0000 (18:51 +0300)
committerMaksym Mamontov <madf@madf.info>
Sun, 24 Jul 2022 15:51:46 +0000 (18:51 +0300)
33 files changed:
include/stg/admin_conf.h
include/stg/corp_conf.h
include/stg/optional.h [deleted file]
include/stg/service_conf.h
include/stg/splice.h [new file with mode: 0644]
include/stg/tariff_conf.h
include/stg/user_conf.h
include/stg/user_stat.h
include/stg/user_traff.h
libs/srvconf/parsers/chg_admin.cpp
libs/srvconf/parsers/chg_tariff.cpp
libs/srvconf/parsers/chg_user.cpp
libs/srvconf/parsers/get_tariff.cpp
libs/srvconf/parsers/optional_utils.h
libs/srvconf/servconf.cpp
projects/sgconf/actions.h
projects/sgconf/admins.cpp
projects/sgconf/config.h
projects/sgconf/corps.cpp
projects/sgconf/info.cpp
projects/sgconf/main.cpp
projects/sgconf/makeproto.h [new file with mode: 0644]
projects/sgconf/services.cpp
projects/sgconf/tariffs.cpp
projects/sgconf/users.cpp
projects/sgconf/utils.h
projects/sgconf/xml.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_admins.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_admins.h
projects/stargazer/plugins/configuration/sgconfig/parser_services.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_tariffs.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_users.cpp
projects/stargazer/plugins/configuration/sgconfig/parser_users.h

index 8531647e055f8a10bf39f239441788315b872828..b402e2417c36d4a5f27e331783e93a5e43657096 100644 (file)
@@ -1,8 +1,7 @@
 #pragma once
 
-#include "stg/optional.h"
-
 #include <string>
+#include <optional>
 
 #include <cstdint>
 
@@ -78,9 +77,9 @@ struct AdminConf
 //-----------------------------------------------------------------------------
 struct AdminConfOpt
 {
-    Optional<Priv> priv;
-    Optional<std::string> login;
-    Optional<std::string> password;
+    std::optional<Priv> priv;
+    std::optional<std::string> login;
+    std::optional<std::string> password;
 };
 
 }
index 6b1cbb83342cc085be68c03e8779eaa5222887cb..8ff4094f6a40aaabd3089295164c86b40d66df2d 100644 (file)
@@ -20,9 +20,8 @@
 
 #pragma once
 
-#include "stg/optional.h"
-
 #include <string>
+#include <optional>
 
 namespace STG
 {
@@ -46,8 +45,8 @@ struct CorpConf
 
 struct CorpConfOpt
 {
-    Optional<std::string> name;
-    Optional<double>      cash;
+    std::optional<std::string> name;
+    std::optional<double>      cash;
 };
 
 }
diff --git a/include/stg/optional.h b/include/stg/optional.h
deleted file mode 100644 (file)
index 105d7e2..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#pragma once
-
-namespace STG
-{
-
-template <typename T>
-class Optional
-{
-public:
-    using value_type = T;
-
-    Optional() noexcept : m_isSet(false) {}
-    explicit Optional(const T& value) noexcept : m_value(value), m_isSet(true) {}
-
-    Optional(const Optional<T>&) = default;
-    Optional<T>& operator=(const Optional<T>&) = default;
-
-    Optional(Optional<T>&&) = default;
-    Optional<T>& operator=(Optional<T>&&) = default;
-
-    Optional<T>& operator=(const T & rhs) noexcept
-    {
-        m_value = rhs;
-        m_isSet = true;
-        return *this;
-    }
-
-    const T & const_data() const noexcept { return m_value; }
-    T & data() noexcept { return m_value; }
-    const T & data() const noexcept { return m_value; }
-    bool empty() const noexcept { return !m_isSet; }
-    void reset() noexcept { m_isSet = false; }
-    void splice(const Optional<T>& rhs) noexcept
-    {
-        if (rhs.m_isSet)
-        {
-            m_value = rhs.m_value;
-            m_isSet = true;
-        }
-    }
-    const T& get(const T& defaultValue) const noexcept
-    {
-        if (m_isSet)
-            return m_value;
-        else
-            return defaultValue;
-    }
-
-private:
-    value_type m_value;
-    bool       m_isSet;
-};
-
-}
index 6be8e70b860502253df2ad5e067cc2975d79bf92..d5661c09d7d182f230e598ecb7ba110f72f37f3a 100644 (file)
 
 #pragma once
 
-#include "stg/optional.h"
+#include "splice.h"
 
 #include <string>
+#include <optional>
 #include <cstdint>
 
 namespace STG
@@ -85,26 +86,26 @@ struct ServiceConfOpt
 
     void splice(const ServiceConfOpt& rhs)
     {
-        name.splice(rhs.name);
-        comment.splice(rhs.comment);
-        cost.splice(rhs.cost);
-        payDay.splice(rhs.payDay);
+        STG::splice(name, rhs.name);
+        STG::splice(comment, rhs.comment);
+        STG::splice(cost, rhs.cost);
+        STG::splice(payDay, rhs.payDay);
     }
 
     ServiceConf get(const ServiceConf& defaultValue) const noexcept
     {
         ServiceConf res;
-        res.name = name.get(defaultValue.name);
-        res.comment = comment.get(defaultValue.comment);
-        res.cost = cost.get(defaultValue.cost);
-        res.payDay = payDay.get(defaultValue.payDay);
+        res.name = name.value_or(defaultValue.name);
+        res.comment = comment.value_or(defaultValue.comment);
+        res.cost = cost.value_or(defaultValue.cost);
+        res.payDay = payDay.value_or(defaultValue.payDay);
         return res;
     }
 
-    Optional<std::string> name;
-    Optional<std::string> comment;
-    Optional<double>      cost;
-    Optional<uint8_t>     payDay;
+    std::optional<std::string> name;
+    std::optional<std::string> comment;
+    std::optional<double>      cost;
+    std::optional<uint8_t>     payDay;
 };
 
 }
diff --git a/include/stg/splice.h b/include/stg/splice.h
new file mode 100644 (file)
index 0000000..8d64630
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
+ */
+
+#pragma once
+
+#include <optional>
+
+namespace STG
+{
+
+template<typename T>
+inline
+void splice(std::optional<T>& lhs, const std::optional<T>& rhs) noexcept
+{
+    if (rhs)
+        lhs = rhs.value();
+}
+
+}
index d7336157936afc6b591fc0f80621e446d3f0af7b..0a4f988b904a5c166f64d98c224975ede8696013 100644 (file)
 #pragma once
 
 #include "tariff.h"
-#include "stg/optional.h"
 #include "const.h"
+#include "splice.h"
 
 #include <string>
 #include <vector>
+#include <optional>
 
 namespace STG
 {
@@ -105,47 +106,47 @@ struct DirPriceDataOpt
 
     void splice(const DirPriceDataOpt & rhs) noexcept
     {
-        hDay.splice(rhs.hDay);
-        mDay.splice(rhs.mDay);
-        hNight.splice(rhs.hNight);
-        mNight.splice(rhs.mNight);
-        priceDayA.splice(rhs.priceDayA);
-        priceNightA.splice(rhs.priceNightA);
-        priceDayB.splice(rhs.priceDayB);
-        priceNightB.splice(rhs.priceNightB);
-        threshold.splice(rhs.threshold);
-        singlePrice.splice(rhs.singlePrice);
-        noDiscount.splice(rhs.noDiscount);
+        STG::splice(hDay, rhs.hDay);
+        STG::splice(mDay, rhs.mDay);
+        STG::splice(hNight, rhs.hNight);
+        STG::splice(mNight, rhs.mNight);
+        STG::splice(priceDayA, rhs.priceDayA);
+        STG::splice(priceNightA, rhs.priceNightA);
+        STG::splice(priceDayB, rhs.priceDayB);
+        STG::splice(priceNightB, rhs.priceNightB);
+        STG::splice(threshold, rhs.threshold);
+        STG::splice(singlePrice, rhs.singlePrice);
+        STG::splice(noDiscount, rhs.noDiscount);
     }
 
     DirPriceData get(const DirPriceData& defaultValue) const noexcept
     {
         DirPriceData res;
-        res.hDay = hDay.get(defaultValue.hDay);
-        res.mDay = mDay.get(defaultValue.mDay);
-        res.hNight = hNight.get(defaultValue.hNight);
-        res.mNight = mNight.get(defaultValue.mNight);
-        res.priceDayA = priceDayA.get(defaultValue.priceDayA);
-        res.priceNightA = priceNightA.get(defaultValue.priceNightA);
-        res.priceDayB = priceDayB.get(defaultValue.priceDayB);
-        res.priceNightB = priceNightB.get(defaultValue.priceNightB);
-        res.threshold = threshold.get(defaultValue.threshold);
-        res.singlePrice = singlePrice.get(defaultValue.singlePrice);
-        res.noDiscount = noDiscount.get(defaultValue.noDiscount);
+        res.hDay = hDay.value_or(defaultValue.hDay);
+        res.mDay = mDay.value_or(defaultValue.mDay);
+        res.hNight = hNight.value_or(defaultValue.hNight);
+        res.mNight = mNight.value_or(defaultValue.mNight);
+        res.priceDayA = priceDayA.value_or(defaultValue.priceDayA);
+        res.priceNightA = priceNightA.value_or(defaultValue.priceNightA);
+        res.priceDayB = priceDayB.value_or(defaultValue.priceDayB);
+        res.priceNightB = priceNightB.value_or(defaultValue.priceNightB);
+        res.threshold = threshold.value_or(defaultValue.threshold);
+        res.singlePrice = singlePrice.value_or(defaultValue.singlePrice);
+        res.noDiscount = noDiscount.value_or(defaultValue.noDiscount);
         return res;
     }
 
-    Optional<int>    hDay;
-    Optional<int>    mDay;
-    Optional<int>    hNight;
-    Optional<int>    mNight;
-    Optional<double> priceDayA;
-    Optional<double> priceNightA;
-    Optional<double> priceDayB;
-    Optional<double> priceNightB;
-    Optional<int>    threshold;
-    Optional<int>    singlePrice;
-    Optional<int>    noDiscount;
+    std::optional<int>    hDay;
+    std::optional<int>    mDay;
+    std::optional<int>    hNight;
+    std::optional<int>    mNight;
+    std::optional<double> priceDayA;
+    std::optional<double> priceNightA;
+    std::optional<double> priceDayB;
+    std::optional<double> priceNightB;
+    std::optional<int>    threshold;
+    std::optional<int>    singlePrice;
+    std::optional<int>    noDiscount;
 };
 //-----------------------------------------------------------------------------
 struct TariffConf
@@ -220,25 +221,25 @@ struct TariffConfOpt
     TariffConf get(const TariffConf& defaultValue) const noexcept
     {
         TariffConf res;
-        res.fee = fee.get(defaultValue.fee);
-        res.free = free.get(defaultValue.free);
-        res.traffType = traffType.get(defaultValue.traffType);
-        res.passiveCost = passiveCost.get(defaultValue.passiveCost);
-        res.name = name.get(defaultValue.name);
-        res.period = period.get(defaultValue.period);
-        res.changePolicy = changePolicy.get(defaultValue.changePolicy);
-        res.changePolicyTimeout = changePolicyTimeout.get(defaultValue.changePolicyTimeout);
+        res.fee = fee.value_or(defaultValue.fee);
+        res.free = free.value_or(defaultValue.free);
+        res.traffType = traffType.value_or(defaultValue.traffType);
+        res.passiveCost = passiveCost.value_or(defaultValue.passiveCost);
+        res.name = name.value_or(defaultValue.name);
+        res.period = period.value_or(defaultValue.period);
+        res.changePolicy = changePolicy.value_or(defaultValue.changePolicy);
+        res.changePolicyTimeout = changePolicyTimeout.value_or(defaultValue.changePolicyTimeout);
         return res;
     }
 
-    Optional<double>             fee;
-    Optional<double>             free;
-    Optional<Tariff::TraffType>  traffType;
-    Optional<double>             passiveCost;
-    Optional<std::string>        name;
-    Optional<Tariff::Period>     period;
-    Optional<Tariff::ChangePolicy> changePolicy;
-    Optional<time_t>             changePolicyTimeout;
+    std::optional<double>             fee;
+    std::optional<double>             free;
+    std::optional<Tariff::TraffType>  traffType;
+    std::optional<double>             passiveCost;
+    std::optional<std::string>        name;
+    std::optional<Tariff::Period>     period;
+    std::optional<Tariff::ChangePolicy> changePolicy;
+    std::optional<time_t>             changePolicyTimeout;
 };
 //-----------------------------------------------------------------------------
 struct TariffData
index db5773b824ce9ff1d3f8169b811c6beafedbc01f..a82c4f1f76790926661dad38964fae2539cd54ce 100644 (file)
@@ -1,10 +1,10 @@
 #pragma once
 
 #include "user_ips.h"
-#include "stg/optional.h"
 
 #include <string>
 #include <vector>
+#include <optional>
 #include <cstdint>
 #include "const.h"
 
@@ -110,25 +110,25 @@ struct UserConfOpt
     UserConfOpt(UserConfOpt&&) = default;
     UserConfOpt& operator=(UserConfOpt&&) = default;
 
-    Optional<std::string>               password;
-    Optional<int>                       passive;
-    Optional<int>                       disabled;
-    Optional<int>                       disabledDetailStat;
-    Optional<int>                       alwaysOnline;
-    Optional<std::string>               tariffName;
-    Optional<std::string>               address;
-    Optional<std::string>               phone;
-    Optional<std::string>               email;
-    Optional<std::string>               note;
-    Optional<std::string>               realName;
-    Optional<std::string>               corp;
-    Optional<std::string>               group;
-    Optional<double>                    credit;
-    Optional<std::string>               nextTariff;
-    std::vector<Optional<std::string> > userdata;
-    Optional<std::vector<std::string> > services;
-    Optional<time_t>                    creditExpire;
-    Optional<UserIPs>                   ips;
+    std::optional<std::string>               password;
+    std::optional<int>                       passive;
+    std::optional<int>                       disabled;
+    std::optional<int>                       disabledDetailStat;
+    std::optional<int>                       alwaysOnline;
+    std::optional<std::string>               tariffName;
+    std::optional<std::string>               address;
+    std::optional<std::string>               phone;
+    std::optional<std::string>               email;
+    std::optional<std::string>               note;
+    std::optional<std::string>               realName;
+    std::optional<std::string>               corp;
+    std::optional<std::string>               group;
+    std::optional<double>                    credit;
+    std::optional<std::string>               nextTariff;
+    std::vector<std::optional<std::string> > userdata;
+    std::optional<std::vector<std::string> > services;
+    std::optional<time_t>                    creditExpire;
+    std::optional<UserIPs>                   ips;
 };
 //-----------------------------------------------------------------------------
 }
index a486a56efe8eca612a13b32542e78d7e33e9acc4..0ecd9e15b43274a3dbabb4ccbf1198e778ca6c3f 100644 (file)
@@ -20,7 +20,6 @@
 
 #pragma once
 
-#include "stg/optional.h"
 #include "user_traff.h"
 
 #include <ctime>
@@ -28,6 +27,7 @@
 #include <map>
 #include <utility>
 #include <string>
+#include <optional>
 
 namespace STG
 {
@@ -180,14 +180,14 @@ struct UserStatOpt
     UserStatOpt(UserStatOpt&&) = default;
     UserStatOpt& operator=(UserStatOpt&&) = default;
 
-    Optional<double>    cash;
-    Optional<CashInfo>  cashAdd;
-    Optional<CashInfo>  cashSet;
-    Optional<double>    freeMb;
-    Optional<double>    lastCashAdd;
-    Optional<time_t>    lastCashAddTime;
-    Optional<time_t>    passiveTime;
-    Optional<time_t>    lastActivityTime;
+    std::optional<double>    cash;
+    std::optional<CashInfo>  cashAdd;
+    std::optional<CashInfo>  cashSet;
+    std::optional<double>    freeMb;
+    std::optional<double>    lastCashAdd;
+    std::optional<time_t>    lastCashAddTime;
+    std::optional<time_t>    passiveTime;
+    std::optional<time_t>    lastActivityTime;
     DirTraffOpt         sessionUp;
     DirTraffOpt         sessionDown;
     DirTraffOpt         monthUp;
index b949da5fc2583534bc3d5fd89c8c0f16f2c3f95b..af5a0b64cc8ea8db940b73b5ff90120ab1a402a4 100644 (file)
 
 #pragma once
 
-#include "stg/optional.h"
 #include "const.h"
 
 #include <ostream>
 #include <vector>
+#include <optional>
 #include <cstdint>
 
 namespace STG
@@ -74,7 +74,7 @@ std::ostream& operator<<(std::ostream& stream, const DirTraff& traff)
 class DirTraffOpt
 {
     public:
-        using ValueType = Optional<uint64_t>;
+        using ValueType = std::optional<uint64_t>;
         using ContainerType = std::vector<ValueType>;
         using IndexType = ContainerType::size_type;
 
index 31fbd4a4322f35f0e053ce3be6f51d140fd0b573..bb4d86823f5676025246399d0569f7e7ca30b7a5 100644 (file)
@@ -30,11 +30,11 @@ using namespace STG;
 std::string ChgAdmin::serialize(const AdminConfOpt& conf, const std::string& /*encoding*/)
 {
     std::string params;
-    if (!conf.login.empty())
-        params += " login=\"" + conf.login.data() + "\"";
-    if (!conf.password.empty())
-        params += " password=\"" + conf.password.data() + "\"";
-    if (!conf.priv.empty())
-        params += " priv=\"" + std::to_string(conf.priv.data().toInt()) + "\"";
+    if (conf.login)
+        params += " login=\"" + conf.login.value() + "\"";
+    if (conf.password)
+        params += " password=\"" + conf.password.value() + "\"";
+    if (conf.priv)
+        params += " priv=\"" + std::to_string(conf.priv.value().toInt()) + "\"";
     return params;
 }
index 63c2b1fdd3ef2d00dfb41924ac3411f848e0f764..fc81dd5252c78ee22b433366c2f1733c454a1a75 100644 (file)
@@ -40,11 +40,11 @@ void appendSlashedResetable(std::ostream& stream, const std::string& name, const
     std::string res;
     for (typename A::size_type i = 0; i < array.size(); ++i)
     {
-        if ((array[i].*field).empty()) // All values must be set
+        if (!(array[i].*field)) // All values must be set
             return;
         if (!res.empty())
             res += "/";
-        res += std::to_string((array[i].*field).data());
+        res += std::to_string((array[i].*field).value());
     }
     stream << "<" << name << " value=\"" << res << "\"/>";
 }
@@ -59,18 +59,18 @@ std::string ChgTariff::serialize(const TariffDataOpt& data, const std::string& /
     appendResetableTag(stream, "passiveCost", data.tariffConf.passiveCost);
     appendResetableTag(stream, "free", data.tariffConf.free);
 
-    if (!data.tariffConf.traffType.empty())
-        stream << "<traffType value=\"" + Tariff::toString(data.tariffConf.traffType.data()) + "\"/>";
+    if (data.tariffConf.traffType)
+        stream << "<traffType value=\"" + Tariff::toString(data.tariffConf.traffType.value()) + "\"/>";
 
-    if (!data.tariffConf.period.empty())
-        switch (data.tariffConf.period.data())
+    if (data.tariffConf.period)
+        switch (data.tariffConf.period.value())
         {
             case Tariff::DAY: stream << "<period value=\"day\"/>"; break;
             case Tariff::MONTH: stream << "<period value=\"month\"/>"; break;
         }
 
-    if (!data.tariffConf.changePolicy.empty())
-        switch (data.tariffConf.changePolicy.data())
+    if (data.tariffConf.changePolicy)
+        switch (data.tariffConf.changePolicy.value())
         {
             case Tariff::ALLOW: stream << "<changePolicy value=\"allow\"/>"; break;
             case Tariff::TO_CHEAP: stream << "<changePolicy value=\"to_cheap\"/>"; break;
@@ -80,14 +80,14 @@ std::string ChgTariff::serialize(const TariffDataOpt& data, const std::string& /
 
     appendResetableTag(stream, "changePolicyTimeout", data.tariffConf.changePolicyTimeout);
     for (size_t i = 0; i < DIR_NUM; ++i)
-        if (!data.dirPrice[i].hDay.empty() &&
-            !data.dirPrice[i].mDay.empty() &&
-            !data.dirPrice[i].hNight.empty() &&
-            !data.dirPrice[i].mNight.empty())
-            stream << "<time" << i << " value=\"" << data.dirPrice[i].hDay.data() << ":"
-                                                  << data.dirPrice[i].mDay.data() << "-"
-                                                  << data.dirPrice[i].hNight.data() << ":"
-                                                  << data.dirPrice[i].mNight.data() << "\"/>";
+        if (data.dirPrice[i].hDay ||
+            data.dirPrice[i].mDay ||
+            data.dirPrice[i].hNight ||
+            data.dirPrice[i].mNight)
+            stream << "<time" << i << " value=\"" << data.dirPrice[i].hDay.value() << ":"
+                                                  << data.dirPrice[i].mDay.value() << "-"
+                                                  << data.dirPrice[i].hNight.value() << ":"
+                                                  << data.dirPrice[i].mNight.value() << "\"/>";
 
     appendSlashedResetable(stream, "priceDayA", data.dirPrice, &DirPriceDataOpt::priceDayA);
     appendSlashedResetable(stream, "priceDayB", data.dirPrice, &DirPriceDataOpt::priceDayB);
index c0a08382d67f6f1b9e873bc4b726460433acd3dd..42682f585549eb5384e764dc5376a42c79e69b8c 100644 (file)
@@ -86,10 +86,10 @@ std::string ChgUser::serialize(const UserConfOpt& conf, const UserStatOpt& stat,
     appendResetableTag(stream, "aonline", conf.alwaysOnline); // TODO: aonline -> alwaysOnline
     appendResetableTag(stream, "ip", conf.ips); // TODO: ip -> ips
 
-    if (!conf.nextTariff.empty())
-        stream << "<tariff delayed=\"" << conf.nextTariff.data() << "\"/>";
-    else if (!conf.tariffName.empty())
-        stream << "<tariff now=\"" << conf.tariffName.data() << "\"/>";
+    if (conf.nextTariff)
+        stream << "<tariff delayed=\"" << conf.nextTariff.value() << "\"/>";
+    else if (conf.tariffName)
+        stream << "<tariff now=\"" << conf.tariffName.value() << "\"/>";
 
     appendResetableTag(stream, "note", maybeEncode(maybeIconv(conf.note, encoding, "koi8-ru")));
     appendResetableTag(stream, "name", maybeEncode(maybeIconv(conf.realName, encoding, "koi8-ru"))); // TODO: name -> realName
@@ -102,36 +102,36 @@ std::string ChgUser::serialize(const UserConfOpt& conf, const UserStatOpt& stat,
     for (size_t i = 0; i < conf.userdata.size(); ++i)
         appendResetableTag(stream, "userdata", i, maybeEncode(maybeIconv(conf.userdata[i], encoding, "koi8-ru")));
 
-    if (!conf.services.empty())
+    if (conf.services)
     {
         stream << "<services>";
-        for (size_t i = 0; i < conf.services.data().size(); ++i)
-            stream << "<service name=\"" << conf.services.data()[i] << "\"/>";
+        for (const auto& service : conf.services.value())
+            stream << "<service name=\"" << service << "\"/>";
         stream << "</services>";
     }
 
     // Stat
 
-    if (!stat.cashAdd.empty())
-        stream << "<cash add=\"" << stat.cashAdd.data().first << "\" msg=\"" << IconvString(Encode12str(stat.cashAdd.data().second), encoding, "koi8-ru") << "\"/>";
-    else if (!stat.cashSet.empty())
-        stream << "<cash set=\"" << stat.cashSet.data().first << "\" msg=\"" << IconvString(Encode12str(stat.cashSet.data().second), encoding, "koi8-ru") << "\"/>";
+    if (stat.cashAdd)
+        stream << "<cash add=\"" << stat.cashAdd.value().first << "\" msg=\"" << IconvString(Encode12str(stat.cashAdd.value().second), encoding, "koi8-ru") << "\"/>";
+    else if (stat.cashSet)
+        stream << "<cash set=\"" << stat.cashSet.value().first << "\" msg=\"" << IconvString(Encode12str(stat.cashSet.value().second), encoding, "koi8-ru") << "\"/>";
 
     appendResetableTag(stream, "freeMb", stat.freeMb);
 
     std::ostringstream traff;
     for (size_t i = 0; i < stat.sessionUp.size(); ++i)
-        if (!stat.sessionUp[i].empty())
-            traff << " SU" << i << "=\"" << stat.sessionUp[i].data() << "\"";
+        if (stat.sessionUp[i])
+            traff << " SU" << i << "=\"" << stat.sessionUp[i].value() << "\"";
     for (size_t i = 0; i < stat.sessionDown.size(); ++i)
-        if (!stat.sessionDown[i].empty())
-            traff << " SD" << i << "=\"" << stat.sessionDown[i].data() << "\"";
+        if (stat.sessionDown[i])
+            traff << " SD" << i << "=\"" << stat.sessionDown[i].value() << "\"";
     for (size_t i = 0; i < stat.monthUp.size(); ++i)
-        if (!stat.monthUp[i].empty())
-            traff << " MU" << i << "=\"" << stat.monthUp[i].data() << "\"";
+        if (stat.monthUp[i])
+            traff << " MU" << i << "=\"" << stat.monthUp[i].value() << "\"";
     for (size_t i = 0; i < stat.monthDown.size(); ++i)
-        if (!stat.monthDown[i].empty())
-            traff << " MD" << i << "=\"" << stat.monthDown[i].data() << "\"";
+        if (stat.monthDown[i])
+            traff << " MD" << i << "=\"" << stat.monthDown[i].value() << "\"";
 
     std::string traffData = traff.str();
     if (!traffData.empty())
index 30492968b1ad03caaad66ae8c88d7e236ff3ef5d..af92da0ba473a570cc6ecb50a1cefffec796c018 100644 (file)
@@ -39,7 +39,7 @@ class AoSParser : public BasePropertyParser
     public:
         using Func = bool (*)(const char**, A &, T A::value_type::*);
         AoSParser(A& a, T A::value_type::* fld, Func f) : array(a), field(fld), func(f) {}
-        virtual bool Parse(const char** attr, const std::string& /*attrName*/, const std::string& /*fromEncoding*/) { return func(attr, array, field); }
+        bool Parse(const char** attr, const std::string& /*attrName*/, const std::string& /*fromEncoding*/) override { return func(attr, array, field); }
     private:
         A& array;
         T A::value_type::* field;
index 9b6054bc55bb995f766652100ace2b9412383eca..9cffc1ed696e126bb4c0bc93aac7664eb77e9a44 100644 (file)
 
 #pragma once
 
-#include "stg/optional.h"
 #include "stg/common.h"
 
 #include <string>
 #include <ostream>
+#include <optional>
 
 namespace STG
 {
@@ -87,51 +87,51 @@ void appendAttr<int8_t>(std::ostream& stream, const std::string& name, const int
 
 template <typename T>
 inline
-void appendResetableTag(std::ostream& stream, const std::string& name, const T& value)
+void appendResetableTag(std::ostream& stream, const std::string& name, const std::optional<T>& value)
 {
-    if (!value.empty())
-        appendTag(stream, name, value.const_data());
+    if (value)
+        appendTag(stream, name, value.value());
 }
 
 template <typename T>
 inline
-void appendResetableTag(std::ostream& stream, const std::string& name, size_t suffix, const T& value)
+void appendResetableTag(std::ostream& stream, const std::string& name, size_t suffix, const std::optional<T>& value)
 {
-    if (!value.empty())
-        appendTag(stream, name, suffix, value.const_data());
+    if (value)
+        appendTag(stream, name, suffix, value.value());
 }
 
 template <typename T>
 inline
-void appendResetableAttr(std::ostream& stream, const std::string& name, const T& value)
+void appendResetableAttr(std::ostream& stream, const std::string& name, const std::optional<T>& value)
 {
-    if (!value.empty())
-        appendAttr(stream, name, value.const_data());
+    if (value)
+        appendAttr(stream, name, value.value());
 }
 
 template <typename T>
 inline
-void appendResetableAttr(std::ostream& stream, const std::string& name, size_t suffix, const T& value)
+void appendResetableAttr(std::ostream& stream, const std::string& name, size_t suffix, const std::optional<T>& value)
 {
-    if (!value.empty())
-        appendAttr(stream, name, suffix, value.const_data());
+    if (value)
+        appendAttr(stream, name, suffix, value.value());
 }
 
 inline
-Optional<std::string> maybeEncode(const Optional<std::string>& value)
+std::optional<std::string> maybeEncode(const std::optional<std::string>& value)
 {
-    Optional<std::string> res;
-    if (!value.empty())
-        res = Encode12str(value.data());
+    std::optional<std::string> res;
+    if (value)
+        res = Encode12str(value.value());
     return res;
 }
 
 inline
-Optional<std::string> maybeIconv(const Optional<std::string>& value, const std::string& fromEncoding, const std::string& toEncoding)
+std::optional<std::string> maybeIconv(const std::optional<std::string>& value, const std::string& fromEncoding, const std::string& toEncoding)
 {
-    Optional<std::string> res;
-    if (!value.empty())
-        res = IconvString(value.data(), fromEncoding, toEncoding);
+    std::optional<std::string> res;
+    if (value)
+        res = IconvString(value.value(), fromEncoding, toEncoding);
     return res;
 }
 
index c4e4bdf6c846f7fd11c82fd4a082eef0bc609bb0..c038fd29c7058388d19525f2bc601f3e07857afe 100644 (file)
@@ -108,7 +108,7 @@ bool ServConf::Impl::ParserRecv(const std::string& chunk, bool last, void* data)
         strprintf(&sc->errorMsg, "XML parse error at line %d, %d: %s. Is last: %d",
                   static_cast<int>(XML_GetCurrentLineNumber(sc->parser)),
                   static_cast<int>(XML_GetCurrentColumnNumber(sc->parser)),
-                  XML_ErrorString(XML_GetErrorCode(sc->parser)), (int)last);
+                  XML_ErrorString(XML_GetErrorCode(sc->parser)), static_cast<int>(last));
         return false;
     }
 
@@ -195,7 +195,7 @@ int ServConf::GetTariff(const std::string& name, GetTariff::Callback f, void* da
 
 int ServConf::ChgTariff(const TariffDataOpt& tariffData, Simple::Callback f, void* data)
 {
-    return pImpl->Exec<Simple::Parser>("SetTariff", "<SetTariff name=\"" + tariffData.tariffConf.name.data() + "\">" + ChgTariff::serialize(tariffData, pImpl->Encoding()) + "</SetTariff>", f, data);
+    return pImpl->Exec<Simple::Parser>("SetTariff", "<SetTariff name=\"" + tariffData.tariffConf.name.value() + "\">" + ChgTariff::serialize(tariffData, pImpl->Encoding()) + "</SetTariff>", f, data);
 }
 
 int ServConf::AddTariff(const std::string& name,
@@ -310,7 +310,7 @@ int ServConf::GetCorp(const std::string& name, GetCorp::Callback f, void* data)
 
 int ServConf::ChgCorp(const CorpConfOpt & conf, Simple::Callback f, void* data)
 {
-    return pImpl->Exec<Simple::Parser>("SetCorp", "<SetCorp name=\"" + conf.name.data() + "\">" + ChgCorp::serialize(conf, pImpl->Encoding()) + "</SetCorp>", f, data);
+    return pImpl->Exec<Simple::Parser>("SetCorp", "<SetCorp name=\"" + conf.name.value() + "\">" + ChgCorp::serialize(conf, pImpl->Encoding()) + "</SetCorp>", f, data);
 }
 
 int ServConf::AddCorp(const std::string& name,
index f23e566de1682c6ce7721646d34b300ea37761c6..a078e6b222fa979ead48b8bb441c5159a8494e45 100644 (file)
@@ -25,9 +25,9 @@
 #include "parser_state.h"
 
 #include "stg/common.h"
-#include "stg/optional.h"
 
 #include <string>
+#include <optional>
 
 #include <cassert>
 
@@ -67,7 +67,7 @@ template <typename T>
 class PARAM_ACTION : public ACTION
 {
     public:
-        PARAM_ACTION(STG::Optional<T> & param,
+        PARAM_ACTION(std::optional<T> & param,
                      const T & defaultValue,
                      const std::string & paramDescription)
             : m_param(param),
@@ -75,11 +75,11 @@ class PARAM_ACTION : public ACTION
               m_description(paramDescription),
               m_hasDefault(true)
         {}
-        explicit PARAM_ACTION(STG::Optional<T> & param)
+        explicit PARAM_ACTION(std::optional<T> & param)
             : m_param(param),
               m_hasDefault(false)
         {}
-        PARAM_ACTION(STG::Optional<T> & param,
+        PARAM_ACTION(std::optional<T> & param,
                      const std::string & paramDescription)
             : m_param(param),
               m_description(paramDescription),
@@ -93,7 +93,7 @@ class PARAM_ACTION : public ACTION
         void ParseValue(const std::string & value) override;
 
     private:
-        STG::Optional<T> & m_param;
+        std::optional<T> & m_param;
         T m_defaltValue;
         std::string m_description;
         bool m_hasDefault;
@@ -172,7 +172,7 @@ return PARSER_STATE(false, --argc, ++argv);
 
 template <typename T>
 inline
-std::unique_ptr<ACTION> MakeParamAction(STG::Optional<T> & param,
+std::unique_ptr<ACTION> MakeParamAction(std::optional<T> & param,
                                         const T & defaultValue,
                                         const std::string & paramDescription)
 {
@@ -181,14 +181,14 @@ return std::make_unique<PARAM_ACTION<T>>(param, defaultValue, paramDescription);
 
 template <typename T>
 inline
-std::unique_ptr<ACTION> MakeParamAction(STG::Optional<T> & param)
+std::unique_ptr<ACTION> MakeParamAction(std::optional<T> & param)
 {
 return std::make_unique<PARAM_ACTION<T>>(param);
 }
 
 template <typename T>
 inline
-std::unique_ptr<ACTION> MakeParamAction(STG::Optional<T> & param,
+std::unique_ptr<ACTION> MakeParamAction(std::optional<T> & param,
                                         const std::string & paramDescription)
 {
 return std::make_unique<PARAM_ACTION<T>>(param, paramDescription);
index ea79621462d8048d183465eced0dd4a4c947162a..c0700e313c2e3da5b6808d9ce8153acb50f52653 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "api_action.h"
 #include "options.h"
+#include "makeproto.h"
 #include "config.h"
 #include "utils.h"
 
@@ -53,7 +54,7 @@ params.push_back(SGCONF::API_ACTION::PARAM("priv", "<priv>", "priviledges"));
 return params;
 }
 
-void ConvPriv(const std::string & value, STG::Optional<STG::Priv> & res)
+void ConvPriv(const std::string & value, std::optional<STG::Priv> & res)
 {
 if (value.length() != 9)
     throw SGCONF::ACTION::ERROR("Priviledges value should be a 9-digits length binary number.");
@@ -119,42 +120,24 @@ bool GetAdminsFunction(const SGCONF::CONFIG & config,
                        const std::string & /*arg*/,
                        const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.GetAdmins(GetAdminsCallback, NULL) == STG::st_ok;
+return makeProto(config).GetAdmins(GetAdminsCallback, NULL) == STG::st_ok;
 }
 
 bool GetAdminFunction(const SGCONF::CONFIG & config,
                       const std::string & arg,
                       const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
 // STG currently doesn't support <GetAdmin login="..."/>.
 // So get a list of admins and filter it. 'data' param holds a pointer to 'login'.
 std::string login(arg);
-return proto.GetAdmins(GetAdminCallback, &login) == STG::st_ok;
+return makeProto(config).GetAdmins(GetAdminCallback, &login) == STG::st_ok;
 }
 
 bool DelAdminFunction(const SGCONF::CONFIG & config,
                       const std::string & arg,
                       const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.DelAdmin(arg, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).DelAdmin(arg, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool AddAdminFunction(const SGCONF::CONFIG & config,
@@ -165,13 +148,7 @@ STG::AdminConfOpt conf;
 conf.login = arg;
 SGCONF::MaybeSet(options, "priv", conf.priv, ConvPriv);
 SGCONF::MaybeSet(options, "password", conf.password);
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.AddAdmin(arg, conf, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).AddAdmin(arg, conf, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool ChgAdminFunction(const SGCONF::CONFIG & config,
@@ -182,13 +159,7 @@ STG::AdminConfOpt conf;
 conf.login = arg;
 SGCONF::MaybeSet(options, "priv", conf.priv, ConvPriv);
 SGCONF::MaybeSet(options, "password", conf.password);
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.ChgAdmin(conf, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).ChgAdmin(conf, SimpleCallback, NULL) == STG::st_ok;
 }
 
 } // namespace anonymous
index f5313ef987a8a97c2c949762194b9e9483d5a095..6c2593347843b95b59429fb068f4fc2c16b52dfa 100644 (file)
 
 #pragma once
 
+#include "stg/splice.h"
 #include "stg/common.h"
-#include "stg/optional.h"
 
 #include <string>
+#include <optional>
 #include <cstdint>
 
 namespace SGCONF
@@ -31,53 +32,51 @@ namespace SGCONF
 
 struct CONFIG
 {
-    STG::Optional<std::string> configFile;
-    STG::Optional<std::string> server;
-    STG::Optional<uint16_t> port;
-    STG::Optional<std::string> localAddress;
-    STG::Optional<uint16_t> localPort;
-    STG::Optional<std::string> userName;
-    STG::Optional<std::string> userPass;
-    STG::Optional<bool> showConfig;
+    std::optional<std::string> configFile;
+    std::optional<std::string> server;
+    std::optional<uint16_t> port;
+    std::optional<std::string> localAddress;
+    std::optional<uint16_t> localPort;
+    std::optional<std::string> userName;
+    std::optional<std::string> userPass;
+    std::optional<bool> showConfig;
 
-    CONFIG & operator=(const CONFIG & rhs)
+    CONFIG() = default;
+    CONFIG(const CONFIG&) = default;
+    CONFIG(CONFIG&&) = default;
+
+    CONFIG& operator=(const CONFIG&) = delete;
+    CONFIG& operator=(CONFIG&&) = delete;
+
+    void splice(const CONFIG & rhs) noexcept
     {
-    if (!rhs.configFile.empty())
-        configFile = rhs.configFile;
-    if (!rhs.server.empty())
-        server = rhs.server;
-    if (!rhs.port.empty())
-        port = rhs.port;
-    if (!rhs.localAddress.empty())
-        localAddress = rhs.localAddress;
-    if (!rhs.localPort.empty())
-        localPort = rhs.localPort;
-    if (!rhs.userName.empty())
-        userName = rhs.userName;
-    if (!rhs.userPass.empty())
-        userPass = rhs.userPass;
-    if (!rhs.showConfig.empty())
-        showConfig = rhs.showConfig;
-    return *this;
+        STG::splice(configFile, rhs.configFile);
+        STG::splice(server, rhs.server);
+        STG::splice(port, rhs.port);
+        STG::splice(localAddress, rhs.localAddress);
+        STG::splice(localPort, rhs.localPort);
+        STG::splice(userName, rhs.userName);
+        STG::splice(userPass, rhs.userPass);
+        STG::splice(showConfig, rhs.showConfig);
     }
 
     std::string Serialize() const
     {
     std::string res;
-    if (!configFile.empty())
-        res += "configFile: '" + configFile.data() + "'\n";
-    if (!server.empty())
-        res += "server: '" + server.data() + "'\n";
-    if (!port.empty())
-        res += "port: " + std::to_string(port.data()) + "\n";
-    if (!localAddress.empty())
-        res += "local address: '" + localAddress.data() + "'\n";
-    if (!localPort.empty())
-        res += "local port: " + std::to_string(localPort.data()) + "\n";
-    if (!userName.empty())
-        res += "userName: '" + userName.data() + "'\n";
-    if (!userPass.empty())
-        res += "userPass: '" + userPass.data() + "\n";
+    if (configFile)
+        res += "configFile: '" + configFile.value() + "'\n";
+    if (server)
+        res += "server: '" + server.value() + "'\n";
+    if (port)
+        res += "port: " + std::to_string(port.value()) + "\n";
+    if (localAddress)
+        res += "local address: '" + localAddress.value() + "'\n";
+    if (localPort)
+        res += "local port: " + std::to_string(localPort.value()) + "\n";
+    if (userName)
+        res += "userName: '" + userName.value() + "'\n";
+    if (userPass)
+        res += "userPass: '" + userPass.value() + "\n";
     return res;
     }
 };
index 586ddcd5dffcd2a92d93d541c65b4c0c9c65f7fd..2dd0ffff89a9d51820df0c5354096e771fb59300 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "api_action.h"
 #include "options.h"
+#include "makeproto.h"
 #include "config.h"
 #include "utils.h"
 
@@ -81,39 +82,21 @@ bool GetCorpsFunction(const SGCONF::CONFIG & config,
                       const std::string & /*arg*/,
                       const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.GetCorporations(GetCorpsCallback, NULL) == STG::st_ok;
+return makeProto(config).GetCorporations(GetCorpsCallback, NULL) == STG::st_ok;
 }
 
 bool GetCorpFunction(const SGCONF::CONFIG & config,
                      const std::string & arg,
                      const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.GetCorp(arg, GetCorpCallback, NULL) == STG::st_ok;
+return makeProto(config).GetCorp(arg, GetCorpCallback, NULL) == STG::st_ok;
 }
 
 bool DelCorpFunction(const SGCONF::CONFIG & config,
                      const std::string & arg,
                      const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.DelCorp(arg, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).DelCorp(arg, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool AddCorpFunction(const SGCONF::CONFIG & config,
@@ -123,13 +106,7 @@ bool AddCorpFunction(const SGCONF::CONFIG & config,
 STG::CorpConfOpt conf;
 conf.name = arg;
 SGCONF::MaybeSet(options, "cash", conf.cash);
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.AddCorp(arg, conf, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).AddCorp(arg, conf, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool ChgCorpFunction(const SGCONF::CONFIG & config,
@@ -139,13 +116,7 @@ bool ChgCorpFunction(const SGCONF::CONFIG & config,
 STG::CorpConfOpt conf;
 conf.name = arg;
 SGCONF::MaybeSet(options, "cash", conf.cash);
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.ChgCorp(conf, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).ChgCorp(conf, SimpleCallback, NULL) == STG::st_ok;
 }
 
 } // namespace anonymous
index 421e438900e3ae44db218015a02db9f85e1d5233..cf6d44a451131cea3d5f5a79102a1a7a8c2b2a06 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "api_action.h"
 #include "options.h"
+#include "makeproto.h"
 #include "config.h"
 
 #include "stg/servconf.h"
@@ -42,13 +43,7 @@ bool InfoFunction(const SGCONF::CONFIG & config,
                   const std::string& /*arg*/,
                   const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.ServerInfo(InfoCallback, NULL) == STG::st_ok;
+return makeProto(config).ServerInfo(InfoCallback, NULL) == STG::st_ok;
 }
 
 }
index 3413dbd9177cb74e71ff6275605a1e0cb7c5b806..60cc15face2b7edf4f56c6fe6b57a2570262b9f3 100644 (file)
@@ -236,227 +236,88 @@ return std::make_unique<CONFIG_ACTION>(config, paramDescription);
 //-----------------------------------------------------------------------------
 int main(int argc, char **argv)
 {
-std::string self(basename(argv[0]));
-SGCONF::CONFIG config;
-SGCONF::COMMANDS commands;
-
-SGCONF::OPTION_BLOCKS blocks;
-blocks.Add("General options")
-      .Add("c", "config", SGCONF::MakeParamAction(config.configFile, std::string("~/.config/stg/sgconf.conf"), "<config file>"), "override default config file")
-      .Add("h", "help", SGCONF::MakeFunc0Action(bind0(Method1Adapt(&SGCONF::OPTION_BLOCKS::Help, blocks), 0)), "\t\tshow this help and exit")
-      //.Add("help-all", SGCONF::MakeFunc0Action(UsageAll), "\t\tshow full help and exit")
-      .Add("v", "version", SGCONF::MakeFunc0Action(bind0(Func1Adapt(Version), self)), "\t\tshow version information and exit");
-SGCONF::OPTION_BLOCK & block = blocks.Add("Connection options")
-      .Add("s", "server", SGCONF::MakeParamAction(config.server, std::string("localhost"), "<address>"), "\t\thost to connect")
-      .Add("p", "port", SGCONF::MakeParamAction(config.port, uint16_t(5555), "<port>"), "\t\tport to connect")
-      .Add("local-address", SGCONF::MakeParamAction(config.localAddress, std::string(""), "<address>"), "\tlocal address to bind")
-      .Add("local-port", SGCONF::MakeParamAction(config.localPort, uint16_t(0), "<port>"), "\t\tlocal port to bind")
-      .Add("u", "username", SGCONF::MakeParamAction(config.userName, std::string("admin"), "<username>"), "\tadministrative login")
-      .Add("w", "userpass", SGCONF::MakeParamAction(config.userPass, "<password>"), "\tpassword for the administrative login")
-      .Add("a", "address", SGCONF::MakeParamAction(config, "<connection string>"), "connection params as a single string in format: <login>:<password>@<host>:<port>");
-blocks.Add("Debug options")
-      .Add("show-config", SGCONF::MakeParamAction(config.showConfig), "\tshow config and exit");
-SGCONF::AppendXMLOptionBlock(commands, blocks);
-SGCONF::AppendServerInfoBlock(commands, blocks);
-SGCONF::AppendAdminsOptionBlock(commands, blocks);
-SGCONF::AppendTariffsOptionBlock(commands, blocks);
-SGCONF::AppendUsersOptionBlock(commands, blocks);
-SGCONF::AppendServicesOptionBlock(commands, blocks);
-SGCONF::AppendCorpsOptionBlock(commands, blocks);
-
-SGCONF::PARSER_STATE state(false, argc, argv);
-
-try
-{
-state = blocks.Parse(--argc, ++argv); // Skipping self name
-}
-catch (const SGCONF::OPTION::ERROR& ex)
-{
-std::cerr << ex.what() << "\n";
-return -1;
-}
-
-if (state.stop)
-    return 0;
-
-if (state.argc > 0)
+    std::string self(basename(argv[0]));
+    SGCONF::CONFIG config;
+    SGCONF::COMMANDS commands;
+
+    SGCONF::OPTION_BLOCKS blocks;
+    blocks.Add("General options")
+          .Add("c", "config", SGCONF::MakeParamAction(config.configFile, std::string("~/.config/stg/sgconf.conf"), "<config file>"), "override default config file")
+          .Add("h", "help", SGCONF::MakeFunc0Action(bind0(Method1Adapt(&SGCONF::OPTION_BLOCKS::Help, blocks), 0)), "\t\tshow this help and exit")
+          //.Add("help-all", SGCONF::MakeFunc0Action(UsageAll), "\t\tshow full help and exit")
+          .Add("v", "version", SGCONF::MakeFunc0Action(bind0(Func1Adapt(Version), self)), "\t\tshow version information and exit");
+    SGCONF::OPTION_BLOCK & block = blocks.Add("Connection options")
+          .Add("s", "server", SGCONF::MakeParamAction(config.server, std::string("localhost"), "<address>"), "\t\thost to connect")
+          .Add("p", "port", SGCONF::MakeParamAction(config.port, uint16_t(5555), "<port>"), "\t\tport to connect")
+          .Add("local-address", SGCONF::MakeParamAction(config.localAddress, std::string(""), "<address>"), "\tlocal address to bind")
+          .Add("local-port", SGCONF::MakeParamAction(config.localPort, uint16_t(0), "<port>"), "\t\tlocal port to bind")
+          .Add("u", "username", SGCONF::MakeParamAction(config.userName, std::string("admin"), "<username>"), "\tadministrative login")
+          .Add("w", "userpass", SGCONF::MakeParamAction(config.userPass, "<password>"), "\tpassword for the administrative login")
+          .Add("a", "address", SGCONF::MakeParamAction(config, "<connection string>"), "connection params as a single string in format: <login>:<password>@<host>:<port>");
+    blocks.Add("Debug options")
+          .Add("show-config", SGCONF::MakeParamAction(config.showConfig), "\tshow config and exit");
+    SGCONF::AppendXMLOptionBlock(commands, blocks);
+    SGCONF::AppendServerInfoBlock(commands, blocks);
+    SGCONF::AppendAdminsOptionBlock(commands, blocks);
+    SGCONF::AppendTariffsOptionBlock(commands, blocks);
+    SGCONF::AppendUsersOptionBlock(commands, blocks);
+    SGCONF::AppendServicesOptionBlock(commands, blocks);
+    SGCONF::AppendCorpsOptionBlock(commands, blocks);
+
+    SGCONF::PARSER_STATE state(false, argc, argv);
+
+    try
+    {
+        state = blocks.Parse(--argc, ++argv); // Skipping self name
+    }
+    catch (const SGCONF::OPTION::ERROR& ex)
     {
-    std::cerr << "Unknown option: '" << *state.argv << "'\n";
-    return -1;
+        std::cerr << ex.what() << "\n";
+        return -1;
     }
 
-try
-{
-SGCONF::CONFIG configOverride(config);
+    if (state.stop)
+        return 0;
 
-if (config.configFile.empty())
+    if (state.argc > 0)
     {
-    const char * mainConfigFile = "/etc/sgconf/sgconf.conf";
-    if (access(mainConfigFile, R_OK) == 0)
-        block.ParseFile(mainConfigFile);
-    ReadUserConfigFile(block);
+        std::cerr << "Unknown option: '" << *state.argv << "'\n";
+        return -1;
     }
-else
+
+    try
     {
-    block.ParseFile(config.configFile.data());
-    }
+        // Preserve config values parsed from the command line
+        SGCONF::CONFIG configOverride(config);
+
+        if (!config.configFile)
+        {
+            // Read main config file.
+            const char * mainConfigFile = "/etc/sgconf/sgconf.conf";
+            if (access(mainConfigFile, R_OK) == 0)
+                block.ParseFile(mainConfigFile);
+            // Read XDG-stuff.
+            ReadUserConfigFile(block);
+        }
+        else
+        {
+            // Read user-supplied file.
+            block.ParseFile(config.configFile.value());
+        }
 
-config = configOverride;
+        // Apply overrides from the command line
+        config.splice(configOverride);
 
-if (!config.showConfig.empty() && config.showConfig.data())
+        if (config.showConfig && config.showConfig.value())
+        {
+            std::cout << config.Serialize() << std::endl;
+            return 0;
+        }
+        return commands.Execute(config) ? 0 : -1;
+    }
+    catch (const std::exception& ex)
     {
-    std::cout << config.Serialize() << std::endl;
-    return 0;
+        std::cerr << ex.what() << "\n";
+        return -1;
     }
-return commands.Execute(config) ? 0 : -1;
 }
-catch (const std::exception& ex)
-{
-std::cerr << ex.what() << "\n";
-return -1;
-}
-}
-//-----------------------------------------------------------------------------
-
-namespace
-{
-
-/*void UsageTariffs(bool full)
-{
-std::cout << "Tariffs management options:\n"
-          << "\t--get-tariffs\t\t\t\tget a list of tariffs (subsequent options will define what to show)\n";
-if (full)
-    std::cout << "\t\t--name\t\t\t\tshow tariff's name\n"
-              << "\t\t--fee\t\t\t\tshow tariff's fee\n"
-              << "\t\t--free\t\t\t\tshow tariff's prepaid traffic in terms of cost\n"
-              << "\t\t--passive-cost\t\t\tshow tariff's cost of \"freeze\"\n"
-              << "\t\t--traff-type\t\t\tshow what type of traffix will be accounted by the tariff\n"
-              << "\t\t--dirs\t\t\t\tshow tarification rules for directions\n\n";
-std::cout << "\t--get-tariff\t\t\t\tget the information about tariff\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the tariff to show\n"
-              << "\t\t--fee\t\t\t\tshow tariff's fee\n"
-              << "\t\t--free\t\t\t\tshow tariff's prepaid traffic in terms of cost\n"
-              << "\t\t--passive-cost\t\t\tshow tariff's cost of \"freeze\"\n"
-              << "\t\t--traff-type\t\t\tshow what type of traffix will be accounted by the tariff\n"
-              << "\t\t--dirs\t\t\t\tshow tarification rules for directions\n\n";
-std::cout << "\t--add-tariff\t\t\t\tadd a new tariff\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the tariff to add\n"
-              << "\t\t--fee <fee>\t\t\tstariff's fee\n"
-              << "\t\t--free <free>\t\t\ttariff's prepaid traffic in terms of cost\n"
-              << "\t\t--passive-cost <cost>\t\ttariff's cost of \"freeze\"\n"
-              << "\t\t--traff-type <type>\t\twhat type of traffi will be accounted by the tariff\n"
-              << "\t\t--times <times>\t\t\tslash-separated list of \"day\" time-spans (in form \"hh:mm-hh:mm\") for each direction\n"
-              << "\t\t--prices-day-a <prices>\t\tslash-separated list of prices for \"day\" traffic before threshold for each direction\n"
-              << "\t\t--prices-night-a <prices>\tslash-separated list of prices for \"night\" traffic before threshold for each direction\n"
-              << "\t\t--prices-day-b <prices>\t\tslash-separated list of prices for \"day\" traffic after threshold for each direction\n"
-              << "\t\t--prices-night-b <prices>\tslash-separated list of prices for \"night\" traffic after threshold for each direction\n"
-              << "\t\t--single-prices <yes|no>\tslash-separated list of \"single price\" flags for each direction\n"
-              << "\t\t--no-discounts <yes|no>\t\tslash-separated list of \"no discount\" flags for each direction\n"
-              << "\t\t--thresholds <thresholds>\tslash-separated list of thresholds (in Mb) for each direction\n\n";
-std::cout << "\t--del-tariff\t\t\t\tdelete an existing tariff\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the tariff to delete\n\n";
-std::cout << "\t--chg-tariff\t\t\t\tchange an existing tariff\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the tariff to change\n"
-              << "\t\t--fee <fee>\t\t\tstariff's fee\n"
-              << "\t\t--free <free>\t\t\ttariff's prepaid traffic in terms of cost\n"
-              << "\t\t--passive-cost <cost>\t\ttariff's cost of \"freeze\"\n"
-              << "\t\t--traff-type <type>\t\twhat type of traffix will be accounted by the tariff\n"
-              << "\t\t--dir <N>\t\t\tnumber of direction data to change\n"
-              << "\t\t\t--time <time>\t\t\"day\" time-span (in form \"hh:mm-hh:mm\")\n"
-              << "\t\t\t--price-day-a <price>\tprice for \"day\" traffic before threshold\n"
-              << "\t\t\t--price-night-a <price>\tprice for \"night\" traffic before threshold\n"
-              << "\t\t\t--price-day-b <price>\tprice for \"day\" traffic after threshold\n"
-              << "\t\t\t--price-night-b <price>\tprice for \"night\" traffic after threshold\n"
-              << "\t\t\t--single-price <yes|no>\t\"single price\" flag\n"
-              << "\t\t\t--no-discount <yes|no>\t\"no discount\" flag\n"
-              << "\t\t\t--threshold <threshold>\tthreshold (in Mb)\n\n";
-}
-//-----------------------------------------------------------------------------
-void UsageUsers(bool full)
-{
-std::cout << "Users management options:\n"
-          << "\t--get-users\t\t\t\tget a list of users (subsequent options will define what to show)\n";
-if (full)
-    std::cout << "\n\n";
-std::cout << "\t--get-user\t\t\t\tget the information about user\n";
-if (full)
-    std::cout << "\n\n";
-std::cout << "\t--add-user\t\t\t\tadd a new user\n";
-if (full)
-    std::cout << "\n\n";
-std::cout << "\t--del-user\t\t\t\tdelete an existing user\n";
-if (full)
-    std::cout << "\n\n";
-std::cout << "\t--chg-user\t\t\t\tchange an existing user\n";
-if (full)
-    std::cout << "\n\n";
-std::cout << "\t--check-user\t\t\t\tcheck credentials is valid\n";
-if (full)
-    std::cout << "\n\n";
-std::cout << "\t--send-message\t\t\t\tsend a message to a user\n";
-if (full)
-    std::cout << "\n\n";
-}
-//-----------------------------------------------------------------------------
-void UsageServices(bool full)
-{
-std::cout << "Services management options:\n"
-          << "\t--get-services\t\t\t\tget a list of services (subsequent options will define what to show)\n";
-if (full)
-    std::cout << "\t\t--name\t\t\t\tshow service's name\n"
-              << "\t\t--comment\t\t\tshow a comment to the service\n"
-              << "\t\t--cost\t\t\t\tshow service's cost\n"
-              << "\t\t--pay-day\t\t\tshow service's pay day\n\n";
-std::cout << "\t--get-service\t\t\t\tget the information about service\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the service to show\n"
-              << "\t\t--comment\t\t\tshow a comment to the service\n"
-              << "\t\t--cost\t\t\t\tshow service's cost\n"
-              << "\t\t--pay-day\t\t\tshow service's pay day\n\n";
-std::cout << "\t--add-service\t\t\t\tadd a new service\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the service to add\n"
-              << "\t\t--comment <comment>\t\ta comment to the service\n"
-              << "\t\t--cost <cost>\t\t\tservice's cost\n"
-              << "\t\t--pay-day <day>\t\t\tservice's pay day\n\n";
-std::cout << "\t--del-service\t\t\t\tdelete an existing service\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the service to delete\n\n";
-std::cout << "\t--chg-service\t\t\t\tchange an existing service\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the service to change\n"
-              << "\t\t--comment <comment>\t\ta comment to the service\n"
-              << "\t\t--cost <cost>\t\t\tservice's cost\n"
-              << "\t\t--pay-day <day>\t\t\tservice's pay day\n\n";
-}
-//-----------------------------------------------------------------------------
-void UsageCorporations(bool full)
-{
-std::cout << "Corporations management options:\n"
-          << "\t--get-corporations\t\t\tget a list of corporations (subsequent options will define what to show)\n";
-if (full)
-    std::cout << "\t\t--name\t\t\t\tshow corporation's name\n"
-              << "\t\t--cash\t\t\t\tshow corporation's cash\n\n";
-std::cout << "\t--get-corp\t\t\t\tget the information about corporation\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the corporation to show\n"
-              << "\t\t--cash\t\t\t\tshow corporation's cash\n\n";
-std::cout << "\t--add-corp\t\t\t\tadd a new corporation\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the corporation to add\n"
-              << "\t\t--cash <cash>\t\t\tinitial corporation's cash (default: \"0\")\n\n";
-std::cout << "\t--del-corp\t\t\t\tdelete an existing corporation\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the corporation to delete\n\n";
-std::cout << "\t--chg-corp\t\t\t\tchange an existing corporation\n";
-if (full)
-    std::cout << "\t\t--name <name>\t\t\tname of the corporation to change\n"
-              << "\t\t--add-cash <amount>[:<message>]\tadd cash to the corporation's account and optional comment message\n"
-              << "\t\t--set-cash <cash>[:<message>]\tnew corporation's cash and optional comment message\n\n";
-}*/
-
-} // namespace anonymous
diff --git a/projects/sgconf/makeproto.h b/projects/sgconf/makeproto.h
new file mode 100644 (file)
index 0000000..82100f4
--- /dev/null
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "config.h"
+
+#include "stg/servconf.h"
+
+namespace SGCONF
+{
+
+inline
+STG::ServConf makeProto(const CONFIG& config)
+{
+    return STG::ServConf(config.server.value(),
+                         config.port.value(),
+                         config.localAddress.value(),
+                         config.localPort.value(),
+                         config.userName.value(),
+                         config.userPass.value());
+}
+
+}
index ede820afb6e7c1d77926391d1b9b3177f9e644d5..2d0caa0426831d1b460643fdd22c3be9514f288a 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "api_action.h"
 #include "options.h"
+#include "makeproto.h"
 #include "config.h"
 #include "utils.h"
 
@@ -85,39 +86,21 @@ bool GetServicesFunction(const SGCONF::CONFIG & config,
                          const std::string & /*arg*/,
                          const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.GetServices(GetServicesCallback, NULL) == STG::st_ok;
+return makeProto(config).GetServices(GetServicesCallback, NULL) == STG::st_ok;
 }
 
 bool GetServiceFunction(const SGCONF::CONFIG & config,
                         const std::string & arg,
                         const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.GetService(arg, GetServiceCallback, NULL) == STG::st_ok;
+return makeProto(config).GetService(arg, GetServiceCallback, NULL) == STG::st_ok;
 }
 
 bool DelServiceFunction(const SGCONF::CONFIG & config,
                         const std::string & arg,
                         const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.DelService(arg, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).DelService(arg, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool AddServiceFunction(const SGCONF::CONFIG & config,
@@ -129,13 +112,7 @@ conf.name = arg;
 SGCONF::MaybeSet(options, "cost", conf.cost);
 SGCONF::MaybeSet(options, "pay-day", conf.payDay);
 SGCONF::MaybeSet(options, "comment", conf.comment);
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.AddService(arg, conf, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).AddService(arg, conf, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool ChgServiceFunction(const SGCONF::CONFIG & config,
@@ -147,13 +124,7 @@ conf.name = arg;
 SGCONF::MaybeSet(options, "cost", conf.cost);
 SGCONF::MaybeSet(options, "pay-day", conf.payDay);
 SGCONF::MaybeSet(options, "comment", conf.comment);
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.ChgService(conf, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).ChgService(conf, SimpleCallback, NULL) == STG::st_ok;
 }
 
 } // namespace anonymous
index 6c5ab3b7354f33077b14fb004f92767d06ed2ca8..23449bb69410ca86c07c9381d3b21e8fcd13a40e 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "api_action.h"
 #include "options.h"
+#include "makeproto.h"
 #include "config.h"
 #include "utils.h"
 
@@ -15,6 +16,7 @@
 #include <sstream>
 #include <string>
 #include <map>
+#include <optional>
 #include <cstdint>
 #include <cassert>
 
@@ -68,7 +70,7 @@ switch (traffType)
 return "unknown";
 }
 
-void ConvPeriod(const std::string & value, STG::Optional<STG::Tariff::Period> & res)
+void ConvPeriod(const std::string & value, std::optional<STG::Tariff::Period> & res)
 {
 std::string lowered = ToLower(value);
 if (lowered == "daily")
@@ -79,7 +81,7 @@ else
     throw SGCONF::ACTION::ERROR("Period should be 'daily' or 'monthly'. Got: '" + value + "'");
 }
 
-void ConvChangePolicy(const std::string & value, STG::Optional<STG::Tariff::ChangePolicy> & res)
+void ConvChangePolicy(const std::string & value, std::optional<STG::Tariff::ChangePolicy> & res)
 {
 std::string lowered = ToLower(value);
 if (lowered == "allow")
@@ -94,7 +96,7 @@ else
     throw SGCONF::ACTION::ERROR("Change policy should be 'allow', 'to_cheap', 'to_expensive' or 'deny'. Got: '" + value + "'");
 }
 
-void ConvChangePolicyTimeout(const std::string & value, STG::Optional<time_t> & res)
+void ConvChangePolicyTimeout(const std::string & value, std::optional<time_t> & res)
 {
 struct tm brokenTime;
 if (stg_strptime(value.c_str(), "%Y-%m-%d %H:%M:%S", &brokenTime) == NULL)
@@ -102,7 +104,7 @@ if (stg_strptime(value.c_str(), "%Y-%m-%d %H:%M:%S", &brokenTime) == NULL)
 res = stg_timegm(&brokenTime);
 }
 
-void ConvTraffType(const std::string & value, STG::Optional<STG::Tariff::TraffType> & res)
+void ConvTraffType(const std::string & value, std::optional<STG::Tariff::TraffType> & res)
 {
 std::string lowered = ToLower(value);
 lowered.erase(std::remove(lowered.begin(), lowered.end(), ' '), lowered.end());
@@ -131,16 +133,16 @@ if (toColon == std::string::npos)
     throw SGCONF::ACTION::ERROR("Time span should be in format 'hh:mm-hh:mm'. Got: '" + value + "'");
 STG::DirPriceDataOpt res;
 res.hDay = FromString<int>(value.substr(0, fromColon));
-if (res.hDay.data() < 0 || res.hDay.data() > 23)
+if (res.hDay.value() < 0 || res.hDay.value() > 23)
     throw SGCONF::ACTION::ERROR("Invalid 'from' hours. Got: '" + value.substr(0, fromColon) + "'");
 res.mDay = FromString<int>(value.substr(fromColon + 1, dashPos - fromColon - 1));
-if (res.mDay.data() < 0 || res.mDay.data() > 59)
+if (res.mDay.value() < 0 || res.mDay.value() > 59)
     throw SGCONF::ACTION::ERROR("Invalid 'from' minutes. Got: '" + value.substr(fromColon + 1, dashPos - fromColon - 1) + "'");
 res.hNight = FromString<int>(value.substr(dashPos + 1, toColon - dashPos - 1));
-if (res.hNight.data() < 0 || res.hNight.data() > 23)
+if (res.hNight.value() < 0 || res.hNight.value() > 23)
     throw SGCONF::ACTION::ERROR("Invalid 'to' hours. Got: '" + value.substr(dashPos + 1, toColon - dashPos - 1) + "'");
 res.mNight = FromString<int>(value.substr(toColon + 1, value.length() - toColon));
-if (res.mNight.data() < 0 || res.mNight.data() > 59)
+if (res.mNight.value() < 0 || res.mNight.value() > 59)
     throw SGCONF::ACTION::ERROR("Invalid 'to' minutes. Got: '" + value.substr(toColon + 1, value.length() - toColon) + "'");
 return res;
 }
@@ -157,9 +159,9 @@ value.erase(std::remove(value.begin(), value.end(), ' '), value.end());
 splice(res, Split<std::vector<STG::DirPriceDataOpt> >(value, ',', ConvTimeSpan));
 }
 
-struct ConvPrice : public std::unary_function<std::string, STG::DirPriceDataOpt>
+struct ConvPrice
 {
-    typedef STG::Optional<double> (STG::DirPriceDataOpt::* MemPtr);
+    using MemPtr = std::optional<double> (STG::DirPriceDataOpt::*);
     ConvPrice(MemPtr before, MemPtr after)
         : m_before(before), m_after(after)
     {}
@@ -167,27 +169,27 @@ struct ConvPrice : public std::unary_function<std::string, STG::DirPriceDataOpt>
     STG::DirPriceDataOpt operator()(const std::string & value)
     {
         STG::DirPriceDataOpt res;
-    size_t slashPos = value.find_first_of('/');
-    if (slashPos == std::string::npos)
+        size_t slashPos = value.find_first_of('/');
+        if (slashPos == std::string::npos)
         {
-        double price = 0;
-        if (str2x(value, price) < 0)
-            throw SGCONF::ACTION::ERROR("Price should be a floating point number. Got: '" + value + "'");
-        (res.*m_before) = (res.*m_after) = price;
-        res.noDiscount = true;
+            double price = 0;
+            if (str2x(value, price) < 0)
+                throw SGCONF::ACTION::ERROR("Price should be a floating point number. Got: '" + value + "'");
+            (res.*m_before) = (res.*m_after) = price;
+            res.noDiscount = true;
         }
-    else
+        else
         {
-        double price = 0;
-        if (str2x(value.substr(0, slashPos), price) < 0)
-            throw SGCONF::ACTION::ERROR("Price should be a floating point number. Got: '" + value.substr(0, slashPos) + "'");
-        (res.*m_before) = price;
-        if (str2x(value.substr(slashPos + 1, value.length() - slashPos), price) < 0)
-            throw SGCONF::ACTION::ERROR("Price should be a floating point number. Got: '" + value.substr(slashPos + 1, value.length() - slashPos) + "'");
-        (res.*m_after) = price;
-        res.noDiscount = false;
+            double price = 0;
+            if (str2x(value.substr(0, slashPos), price) < 0)
+                throw SGCONF::ACTION::ERROR("Price should be a floating point number. Got: '" + value.substr(0, slashPos) + "'");
+            (res.*m_before) = price;
+            if (str2x(value.substr(slashPos + 1, value.length() - slashPos), price) < 0)
+                throw SGCONF::ACTION::ERROR("Price should be a floating point number. Got: '" + value.substr(slashPos + 1, value.length() - slashPos) + "'");
+            (res.*m_after) = price;
+            res.noDiscount = false;
         }
-    return res;
+        return res;
     }
 
     MemPtr m_before;
@@ -327,42 +329,24 @@ bool GetTariffsFunction(const SGCONF::CONFIG & config,
                         const std::string & /*arg*/,
                         const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.GetTariffs(GetTariffsCallback, NULL) == STG::st_ok;
+return makeProto(config).GetTariffs(GetTariffsCallback, NULL) == STG::st_ok;
 }
 
 bool GetTariffFunction(const SGCONF::CONFIG & config,
                        const std::string & arg,
                        const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
 // STG currently doesn't support <GetTariff name="..."/>.
 // So get a list of tariffs and filter it. 'data' param holds a pointer to 'name'.
 std::string name(arg);
-return proto.GetTariffs(GetTariffCallback, &name) == STG::st_ok;
+return makeProto(config).GetTariffs(GetTariffCallback, &name) == STG::st_ok;
 }
 
 bool DelTariffFunction(const SGCONF::CONFIG & config,
                        const std::string & arg,
                        const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.DelTariff(arg, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).DelTariff(arg, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool AddTariffFunction(const SGCONF::CONFIG & config,
@@ -384,20 +368,14 @@ SGCONF::MaybeSet(options, "night-prices", conf.dirPrice, ConvNightPrices);
 SGCONF::MaybeSet(options, "thresholds", conf.dirPrice, ConvThresholds);
 for (size_t i = 0; i < conf.dirPrice.size(); ++i)
     {
-    if (!conf.dirPrice[i].priceDayA.empty() &&
-        !conf.dirPrice[i].priceNightA.empty() &&
-        !conf.dirPrice[i].priceDayB.empty() &&
-        !conf.dirPrice[i].priceNightB.empty())
-        conf.dirPrice[i].singlePrice = conf.dirPrice[i].priceDayA.data() == conf.dirPrice[i].priceNightA.data() &&
-                                       conf.dirPrice[i].priceDayB.data() == conf.dirPrice[i].priceNightB.data();
+    if (conf.dirPrice[i].priceDayA ||
+        conf.dirPrice[i].priceNightA ||
+        conf.dirPrice[i].priceDayB ||
+        conf.dirPrice[i].priceNightB)
+        conf.dirPrice[i].singlePrice = conf.dirPrice[i].priceDayA.value() == conf.dirPrice[i].priceNightA.value() &&
+                                       conf.dirPrice[i].priceDayB.value() == conf.dirPrice[i].priceNightB.value();
     }
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.AddTariff(arg, conf, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).AddTariff(arg, conf, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool ChgTariffFunction(const SGCONF::CONFIG & config,
@@ -419,20 +397,14 @@ SGCONF::MaybeSet(options, "night-prices", conf.dirPrice, ConvNightPrices);
 SGCONF::MaybeSet(options, "thresholds", conf.dirPrice, ConvThresholds);
 for (size_t i = 0; i < conf.dirPrice.size(); ++i)
     {
-    if (!conf.dirPrice[i].priceDayA.empty() &&
-        !conf.dirPrice[i].priceNightA.empty() &&
-        !conf.dirPrice[i].priceDayB.empty() &&
-        !conf.dirPrice[i].priceNightB.empty())
-        conf.dirPrice[i].singlePrice = conf.dirPrice[i].priceDayA.data() == conf.dirPrice[i].priceNightA.data() &&
-                                       conf.dirPrice[i].priceDayB.data() == conf.dirPrice[i].priceNightB.data();
+    if (conf.dirPrice[i].priceDayA ||
+        conf.dirPrice[i].priceNightA ||
+        conf.dirPrice[i].priceDayB ||
+        conf.dirPrice[i].priceNightB)
+        conf.dirPrice[i].singlePrice = conf.dirPrice[i].priceDayA.value() == conf.dirPrice[i].priceNightA.value() &&
+                                       conf.dirPrice[i].priceDayB.value() == conf.dirPrice[i].priceNightB.value();
     }
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.ChgTariff(conf, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).ChgTariff(conf, SimpleCallback, NULL) == STG::st_ok;
 }
 
 } // namespace anonymous
index 3bf5caabb47d838739149c937121f7f54989b63c..d1dd1a7343c594b0b139f9b06964701f0f0b5847 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "api_action.h"
 #include "options.h"
+#include "makeproto.h"
 #include "config.h"
 #include "utils.h"
 
 #include "stg/user_stat.h"
 #include "stg/user_ips.h"
 #include "stg/common.h"
+#include "stg/splice.h"
 
 #include <iostream>
 #include <algorithm>
 #include <string>
 #include <map>
+#include <optional>
 
 namespace
 {
@@ -124,34 +127,34 @@ params.push_back(SGCONF::API_ACTION::PARAM("text", "<text>", "\t\tmessage text")
 return params;
 }
 
-void ConvBool(const std::string & value, STG::Optional<int> & res)
+void ConvBool(const std::string & value, std::optional<int> & res)
 {
 res = !value.empty() && value[0] == 'y';
 }
 
-void Splice(std::vector<STG::Optional<std::string> > & lhs, const std::vector<STG::Optional<std::string> > & rhs)
+void Splice(std::vector<std::optional<std::string> > & lhs, const std::vector<std::optional<std::string> > & rhs)
 {
 for (size_t i = 0; i < lhs.size() && i < rhs.size(); ++i)
-    lhs[i].splice(rhs[i]);
+    STG::splice(lhs[i], rhs[i]);
 }
 
-STG::Optional<std::string> ConvString(const std::string & value)
+std::optional<std::string> ConvString(const std::string & value)
 {
-return STG::Optional<std::string>(value);
+return std::optional<std::string>(value);
 }
 
-void ConvStringList(std::string value, std::vector<STG::Optional<std::string> > & res)
+void ConvStringList(std::string value, std::vector<std::optional<std::string> > & res)
 {
-Splice(res, Split<std::vector<STG::Optional<std::string> > >(value, ',', ConvString));
+Splice(res, Split<std::vector<std::optional<std::string> > >(value, ',', ConvString));
 }
 
-void ConvServices(std::string value, STG::Optional<std::vector<std::string> > & res)
+void ConvServices(std::string value, std::optional<std::vector<std::string> > & res)
 {
 value.erase(std::remove(value.begin(), value.end(), ' '), value.end());
 res = Split<std::vector<std::string> >(value, ',');
 }
 
-void ConvCreditExpire(const std::string & value, STG::Optional<time_t> & res)
+void ConvCreditExpire(const std::string & value, std::optional<time_t> & res)
 {
 struct tm brokenTime;
 if (stg_strptime(value.c_str(), "%Y-%m-%d %H:%M:%S", &brokenTime) == NULL)
@@ -159,7 +162,7 @@ if (stg_strptime(value.c_str(), "%Y-%m-%d %H:%M:%S", &brokenTime) == NULL)
 res = stg_timegm(&brokenTime);
 }
 
-void ConvIPs(const std::string & value, STG::Optional<STG::UserIPs> & res)
+void ConvIPs(const std::string & value, std::optional<STG::UserIPs> & res)
 {
 res = STG::UserIPs::parse(value);
 }
@@ -210,7 +213,7 @@ for (size_t i = 0; i < DIR_NUM; ++i)
     }
 }
 
-void ConvCashInfo(const std::string & value, STG::Optional<STG::CashInfo> & res)
+void ConvCashInfo(const std::string & value, std::optional<STG::CashInfo> & res)
 {
 STG::CashInfo info;
 size_t pos = value.find_first_of(':');
@@ -287,39 +290,21 @@ bool GetUsersFunction(const SGCONF::CONFIG & config,
                       const std::string & /*arg*/,
                       const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.GetUsers(GetUsersCallback, NULL) == STG::st_ok;
+return makeProto(config).GetUsers(GetUsersCallback, NULL) == STG::st_ok;
 }
 
 bool GetUserFunction(const SGCONF::CONFIG & config,
                      const std::string & arg,
                      const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.GetUser(arg, GetUserCallback, NULL) == STG::st_ok;
+return makeProto(config).GetUser(arg, GetUserCallback, NULL) == STG::st_ok;
 }
 
 bool DelUserFunction(const SGCONF::CONFIG & config,
                      const std::string & arg,
                      const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.DelUser(arg, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).DelUser(arg, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool AddUserFunction(const SGCONF::CONFIG & config,
@@ -351,13 +336,7 @@ SGCONF::MaybeSet(options, "cash-set", stat.cashSet, ConvCashInfo);
 SGCONF::MaybeSet(options, "free", stat.freeMb);
 SGCONF::MaybeSet(options, "session-traffic", stat, ConvSessionTraff);
 SGCONF::MaybeSet(options, "month-traffic", stat, ConvMonthTraff);
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.AddUser(arg, conf, stat, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).AddUser(arg, conf, stat, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool ChgUserFunction(const SGCONF::CONFIG & config,
@@ -390,13 +369,7 @@ SGCONF::MaybeSet(options, "cash-set", stat.cashSet, ConvCashInfo);
 SGCONF::MaybeSet(options, "free", stat.freeMb);
 SGCONF::MaybeSet(options, "session-traffic", stat, ConvSessionTraff);
 SGCONF::MaybeSet(options, "month-traffic", stat, ConvMonthTraff);
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.ChgUser(arg, conf, stat, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).ChgUser(arg, conf, stat, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool CheckUserFunction(const SGCONF::CONFIG & config,
@@ -406,13 +379,7 @@ bool CheckUserFunction(const SGCONF::CONFIG & config,
 std::map<std::string, std::string>::const_iterator it(options.find("password"));
 if (it == options.end())
     throw SGCONF::ACTION::ERROR("Password is not specified.");
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.CheckUser(arg, it->second, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).CheckUser(arg, it->second, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool SendMessageFunction(const SGCONF::CONFIG & config,
@@ -430,26 +397,14 @@ it = options.find("text");
 if (it == options.end())
     throw SGCONF::ACTION::ERROR("Message text is not specified.");
 std::string text = it->second;
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.SendMessage(logins, text, SimpleCallback, NULL) == STG::st_ok;
+return makeProto(config).SendMessage(logins, text, SimpleCallback, NULL) == STG::st_ok;
 }
 
 bool AuthByFunction(const SGCONF::CONFIG & config,
                     const std::string & arg,
                     const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.AuthBy(arg, AuthByCallback, NULL) == STG::st_ok;
+return makeProto(config).AuthBy(arg, AuthByCallback, NULL) == STG::st_ok;
 }
 
 } // namespace anonymous
index 6168cbf2f111354fb44969bacc250e8485e6d7dc..3a57d9995f9f5b74c437703f65f73741f4aea2b0 100644 (file)
@@ -1,45 +1,45 @@
 #pragma once
 
 #include "stg/common.h"
-#include "stg/optional.h"
 
 #include <string>
 #include <map>
+#include <optional>
 
 namespace SGCONF
 {
 
 template <typename T>
 inline
-void MaybeSet(const std::map<std::string, std::string> & options, const std::string & name, STG::Optional<T> & res)
+void MaybeSet(const std::map<std::string, std::string> & options, const std::string & name, std::optional<T> & res)
 {
-std::map<std::string, std::string>::const_iterator it(options.find(name));
-if (it == options.end())
-    return;
-T value;
-if (str2x(it->second, value) < 0)
-    return;
-res = value;
+    std::map<std::string, std::string>::const_iterator it(options.find(name));
+    if (it == options.end())
+        return;
+    T value;
+    if (str2x(it->second, value) < 0)
+        return;
+    res = value;
 }
 
 template <typename T, typename F>
 inline
 void MaybeSet(const std::map<std::string, std::string> & options, const std::string & name, T & res, F conv)
 {
-std::map<std::string, std::string>::const_iterator it(options.find(name));
-if (it == options.end())
-    return;
-conv(it->second, res);
+    std::map<std::string, std::string>::const_iterator it(options.find(name));
+    if (it == options.end())
+        return;
+    conv(it->second, res);
 }
 
 template <>
 inline
-void MaybeSet<std::string>(const std::map<std::string, std::string> & options, const std::string & name, STG::Optional<std::string> & res)
+void MaybeSet<std::string>(const std::map<std::string, std::string> & options, const std::string & name, std::optional<std::string> & res)
 {
-std::map<std::string, std::string>::const_iterator it(options.find(name));
-if (it == options.end())
-    return;
-res = it->second;
+    std::map<std::string, std::string>::const_iterator it(options.find(name));
+    if (it == options.end())
+        return;
+    res = it->second;
 }
 
 } // namespace SGCONF
index 61587a14d0b7942b6426d0667171083131e8b44f..93a06e23197926b2967b17af88214bddd793ebe4 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "api_action.h"
 #include "options.h"
+#include "makeproto.h"
 #include "config.h"
 
 #include "stg/servconf.h"
@@ -87,13 +88,7 @@ bool RawXMLFunction(const SGCONF::CONFIG & config,
                     const std::string & arg,
                     const std::map<std::string, std::string> & /*options*/)
 {
-STG::ServConf proto(config.server.data(),
-                    config.port.data(),
-                    config.localAddress.data(),
-                    config.localPort.data(),
-                    config.userName.data(),
-                    config.userPass.data());
-return proto.RawXML(arg, RawXMLCallback, NULL) == STG::st_ok;
+return makeProto(config).RawXML(arg, RawXMLCallback, NULL) == STG::st_ok;
 }
 
 }
index bc47b7fd1ea07718fd4f1cd1319f7d745935368e..1de533d67f48868c6fe543860185943d58a02bfb 100644 (file)
@@ -145,13 +145,13 @@ void CHG_ADMIN::CreateAnswer()
 
         AdminConf conf(origAdmin->conf());
 
-        if (!password.empty())
-            conf.password = password.data();
+        if (password)
+            conf.password = password.value();
 
-        if (!privAsString.empty())
+        if (privAsString)
         {
             int p = 0;
-            if (str2x(privAsString.data().c_str(), p) < 0)
+            if (str2x(privAsString.value().c_str(), p) < 0)
             {
                 m_answer = "<" + m_tag + " Result = \"Incorrect parameter Priv.\"/>";
                 return;
index efad0d63d7510144835fe87fadb739002b5e0aad..4a6924bd614e7cd1fbde4ad0bfa7ea3847fa3dfc 100644 (file)
@@ -24,9 +24,9 @@
 #include "parser.h"
 
 #include "stg/common.h"
-#include "stg/optional.h"
 
 #include <string>
+#include <optional>
 
 namespace STG
 {
@@ -138,8 +138,8 @@ class CHG_ADMIN: public BASE_PARSER
 
     private:
         std::string login;
-        Optional<std::string> password;
-        Optional<std::string> privAsString;
+        std::optional<std::string> password;
+        std::optional<std::string> privAsString;
         Admins & m_admins;
 
         void CreateAnswer() override;
index 118d819e0b4113b7c2089dd8466ff85c7c8bc49d..2ccddd386ef6f2dc28c5fbb6473d9e04804fc451 100644 (file)
@@ -178,20 +178,20 @@ int CHG_SERVICE::Start(void *, const char * el, const char ** attr)
 
 void CHG_SERVICE::CreateAnswer()
 {
-    if (m_service.name.empty())
+    if (!m_service.name)
     {
         m_answer = "<" + m_tag + " result=\"Empty service name.\"/>";
         return;
     }
 
-    if (!m_services.Exists(m_service.name.const_data()))
+    if (!m_services.Exists(m_service.name.value()))
     {
-        m_answer = "<" + m_tag + " result = \"Service '" + m_service.name.const_data() + "' does not exist.\"/>";
+        m_answer = "<" + m_tag + " result = \"Service '" + m_service.name.value() + "' does not exist.\"/>";
         return;
     }
 
     ServiceConf orig;
-    m_services.Find(m_service.name.const_data(), &orig);
+    m_services.Find(m_service.name.value(), &orig);
 
     ServiceConfOpt conf(orig);
     conf.splice(m_service);
index 3ed22113e12d6d0f89f1733087acbefddd536139..e22c78fe72b76a207555670d1350ff5ce78f895f 100644 (file)
@@ -23,8 +23,8 @@
 
 #include "stg/tariffs.h"
 #include "stg/users.h"
-#include "stg/optional.h"
 
+#include <optional>
 #include <cstdio> // snprintf
 #include <cstring>
 
@@ -57,7 +57,7 @@ std::string AOS2String(const A & array, size_t size, const F C::* field, F multi
 }
 
 template <typename T>
-bool str2res(const std::string& source, STG::Optional<T>& dest, T divisor)
+bool str2res(const std::string& source, std::optional<T>& dest, T divisor)
 {
     T value = 0;
     if (str2x(source, value))
@@ -67,7 +67,7 @@ bool str2res(const std::string& source, STG::Optional<T>& dest, T divisor)
 }
 
 template <typename A, typename C, typename F>
-bool String2AOS(const std::string & source, A & array, size_t size, STG::Optional<F> C::* field, F divisor)
+bool String2AOS(const std::string & source, A & array, size_t size, std::optional<F> C::* field, F divisor)
 {
     size_t index = 0;
     std::string::size_type from = 0;
@@ -314,7 +314,7 @@ int CHG_TARIFF::Start(void *, const char * el, const char ** attr)
 
 void CHG_TARIFF::CreateAnswer()
 {
-    if (!td.tariffConf.name.data().empty())
+    if (!td.tariffConf.name.value().empty())
     {
         auto tariffData = td.get({});
         if (m_tariffs.Chg(tariffData, &m_currAdmin) == 0)
index 809afec62ce709878fe000acc77b980e597c795d..68a597c83dd11bb10e563510689c430badf94e3f 100644 (file)
@@ -469,16 +469,16 @@ int CHG_USER::ApplyChanges()
 
     bool check = false;
     bool alwaysOnline = u->GetProperties().alwaysOnline;
-    if (!m_ucr.alwaysOnline.empty())
+    if (m_ucr.alwaysOnline)
     {
         check = true;
-        alwaysOnline = m_ucr.alwaysOnline.const_data();
+        alwaysOnline = m_ucr.alwaysOnline.value();
     }
     bool onlyOneIP = u->GetProperties().ips.ConstData().onlyOneIP();
-    if (!m_ucr.ips.empty())
+    if (m_ucr.ips)
     {
         check = true;
-        onlyOneIP = m_ucr.ips.const_data().onlyOneIP();
+        onlyOneIP = m_ucr.ips.value().onlyOneIP();
     }
 
     if (check && alwaysOnline && !onlyOneIP)
@@ -488,10 +488,10 @@ int CHG_USER::ApplyChanges()
         return -1;
     }
 
-    for (size_t i = 0; i < m_ucr.ips.const_data().count(); ++i)
+    for (size_t i = 0; i < m_ucr.ips.value().count(); ++i)
     {
         ConstUserPtr user;
-        uint32_t ip = m_ucr.ips.const_data().operator[](i).ip;
+        uint32_t ip = m_ucr.ips.value().operator[](i).ip;
         if (m_users.IsIPInUse(ip, m_login, &user))
         {
             printfd(__FILE__, "Trying to assign an IP %s to '%s' that is already in use by '%s'\n", inet_ntostring(ip).c_str(), m_login.c_str(), user->GetLogin().c_str());
@@ -500,50 +500,50 @@ int CHG_USER::ApplyChanges()
         }
     }
 
-    if (!m_ucr.ips.empty())
-        if (!u->GetProperties().ips.Set(m_ucr.ips.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.ips)
+        if (!u->GetProperties().ips.Set(m_ucr.ips.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.alwaysOnline.empty())
-        if (!u->GetProperties().alwaysOnline.Set(m_ucr.alwaysOnline.const_data(),
+    if (m_ucr.alwaysOnline)
+        if (!u->GetProperties().alwaysOnline.Set(m_ucr.alwaysOnline.value(),
                                                  m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.address.empty())
-        if (!u->GetProperties().address.Set(m_ucr.address.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.address)
+        if (!u->GetProperties().address.Set(m_ucr.address.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.creditExpire.empty())
-        if (!u->GetProperties().creditExpire.Set(m_ucr.creditExpire.const_data(),
+    if (m_ucr.creditExpire)
+        if (!u->GetProperties().creditExpire.Set(m_ucr.creditExpire.value(),
                                                  m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.credit.empty())
-        if (!u->GetProperties().credit.Set(m_ucr.credit.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.credit)
+        if (!u->GetProperties().credit.Set(m_ucr.credit.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_usr.freeMb.empty())
-        if (!u->GetProperties().freeMb.Set(m_usr.freeMb.const_data(), m_currAdmin, m_login, m_store))
+    if (m_usr.freeMb)
+        if (!u->GetProperties().freeMb.Set(m_usr.freeMb.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.disabled.empty())
-        if (!u->GetProperties().disabled.Set(m_ucr.disabled.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.disabled)
+        if (!u->GetProperties().disabled.Set(m_ucr.disabled.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.disabledDetailStat.empty())
-        if (!u->GetProperties().disabledDetailStat.Set(m_ucr.disabledDetailStat.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.disabledDetailStat)
+        if (!u->GetProperties().disabledDetailStat.Set(m_ucr.disabledDetailStat.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.email.empty())
-        if (!u->GetProperties().email.Set(m_ucr.email.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.email)
+        if (!u->GetProperties().email.Set(m_ucr.email.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.group.empty())
-        if (!u->GetProperties().group.Set(m_ucr.group.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.group)
+        if (!u->GetProperties().group.Set(m_ucr.group.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.note.empty())
-        if (!u->GetProperties().note.Set(m_ucr.note.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.note)
+        if (!u->GetProperties().note.Set(m_ucr.note.value(), m_currAdmin, m_login, m_store))
             return -1;
 
     std::vector<STG::UserPropertyLogged<std::string> *> userdata;
@@ -559,31 +559,31 @@ int CHG_USER::ApplyChanges()
     userdata.push_back(u->GetProperties().userdata9.GetPointer());
 
     for (size_t i = 0; i < userdata.size(); i++)
-        if (!m_ucr.userdata[i].empty())
-            if(!userdata[i]->Set(m_ucr.userdata[i].const_data(), m_currAdmin, m_login, m_store))
+        if (m_ucr.userdata[i])
+            if(!userdata[i]->Set(m_ucr.userdata[i].value(), m_currAdmin, m_login, m_store))
                 return -1;
 
-    if (!m_ucr.passive.empty())
-        if (!u->GetProperties().passive.Set(m_ucr.passive.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.passive)
+        if (!u->GetProperties().passive.Set(m_ucr.passive.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.password.empty())
-        if (!u->GetProperties().password.Set(m_ucr.password.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.password)
+        if (!u->GetProperties().password.Set(m_ucr.password.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.phone.empty())
-        if (!u->GetProperties().phone.Set(m_ucr.phone.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.phone)
+        if (!u->GetProperties().phone.Set(m_ucr.phone.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_ucr.realName.empty())
-        if (!u->GetProperties().realName.Set(m_ucr.realName.const_data(), m_currAdmin, m_login, m_store))
+    if (m_ucr.realName)
+        if (!u->GetProperties().realName.Set(m_ucr.realName.value(), m_currAdmin, m_login, m_store))
             return -1;
 
-    if (!m_usr.cash.empty())
+    if (m_usr.cash)
     {
         if (m_cashMustBeAdded)
         {
-            if (!u->GetProperties().cash.Set(m_usr.cash.const_data() + u->GetProperties().cash,
+            if (!u->GetProperties().cash.Set(m_usr.cash.value() + u->GetProperties().cash,
                                              m_currAdmin,
                                              m_login,
                                              m_store,
@@ -592,21 +592,21 @@ int CHG_USER::ApplyChanges()
         }
         else
         {
-            if (!u->GetProperties().cash.Set(m_usr.cash.const_data(), m_currAdmin, m_login, m_store, m_cashMsg))
+            if (!u->GetProperties().cash.Set(m_usr.cash.value(), m_currAdmin, m_login, m_store, m_cashMsg))
                 return -1;
         }
     }
 
-    if (!m_ucr.tariffName.empty())
+    if (m_ucr.tariffName)
     {
-        const auto newTariff = m_tariffs.FindByName(m_ucr.tariffName.const_data());
+        const auto newTariff = m_tariffs.FindByName(m_ucr.tariffName.value());
         if (newTariff)
         {
             const auto tariff = u->GetTariff();
             std::string message = tariff->TariffChangeIsAllowed(*newTariff, time(NULL));
             if (message.empty())
             {
-                if (!u->GetProperties().tariffName.Set(m_ucr.tariffName.const_data(), m_currAdmin, m_login, m_store))
+                if (!u->GetProperties().tariffName.Set(m_ucr.tariffName.value(), m_currAdmin, m_login, m_store))
                     return -1;
                 u->ResetNextTariff();
             }
@@ -622,11 +622,11 @@ int CHG_USER::ApplyChanges()
         }
     }
 
-    if (!m_ucr.nextTariff.empty())
+    if (m_ucr.nextTariff)
     {
-        if (m_tariffs.FindByName(m_ucr.nextTariff.const_data()))
+        if (m_tariffs.FindByName(m_ucr.nextTariff.value()))
         {
-            if (!u->GetProperties().nextTariff.Set(m_ucr.nextTariff.const_data(), m_currAdmin, m_login, m_store))
+            if (!u->GetProperties().nextTariff.Set(m_ucr.nextTariff.value(), m_currAdmin, m_login, m_store))
                 return -1;
         }
         else
@@ -642,14 +642,14 @@ int CHG_USER::ApplyChanges()
     int downCount = 0;
     for (int i = 0; i < DIR_NUM; i++)
     {
-        if (!m_upr[i].empty())
+        if (m_upr[i])
         {
-            up[i] = m_upr[i].data();
+            up[i] = m_upr[i].value();
             upCount++;
         }
-        if (!m_downr[i].empty())
+        if (m_downr[i])
         {
-            down[i] = m_downr[i].data();
+            down[i] = m_downr[i].value();
             downCount++;
         }
     }
index b9d5fce464392d42a21e4fb60b37111d1b4298c0..a56acffc74ee47fa7efb0fbe5912cac95bd5112a 100644 (file)
@@ -26,9 +26,9 @@
 #include "stg/user_conf.h"
 #include "stg/user_stat.h"
 #include "stg/common.h"
-#include "stg/optional.h"
 
 #include <string>
+#include <optional>
 
 namespace STG
 {
@@ -160,8 +160,8 @@ class CHG_USER: public BASE_PARSER
         const Tariffs & m_tariffs;
         UserStatOpt m_usr;
         UserConfOpt m_ucr;
-        Optional<uint64_t> m_upr[DIR_NUM];
-        Optional<uint64_t> m_downr[DIR_NUM];
+        std::optional<uint64_t> m_upr[DIR_NUM];
+        std::optional<uint64_t> m_downr[DIR_NUM];
         std::string m_cashMsg;
         std::string m_login;
         bool m_cashMustBeAdded;