]> git.stg.codes - stg.git/blobdiff - include/stg/user_ips.h
Merge remote-tracking branch 'github/master'
[stg.git] / include / stg / user_ips.h
index 250520b28f7eca14cc353020166f9d7ac0048956..35c209256a0714416e3c0c3bfc2fc67f428cdfe2 100644 (file)
  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
  */
 
- /*
- $Revision: 1.22 $
- $Date: 2010/03/04 11:49:53 $
- $Author: faust $
- */
+#pragma once
+
+#include "stg/common.h"
 
-#ifndef USER_IPS_H
-#define USER_IPS_H
+#include <vector>
+#include <string>
+#include <ostream>
+#include <cstring>
+#include <cstdint>
 
 #ifdef FREE_BSD
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
-#include <cstring>
-#include <vector>
-#include <string>
-#include <iostream>
-#include <sstream>
-
-#include "common.h"
-#include "os_int.h"
-
-using namespace std;
+namespace STG
+{
 
 //-------------------------------------------------------------------------
-struct IP_MASK
+struct IPMask
 {
-IP_MASK() : ip(0), mask(0) {}
-IP_MASK(const IP_MASK & ipm) : ip(ipm.ip), mask(ipm.mask)  {}
-uint32_t ip;
-uint32_t mask;
+    IPMask() noexcept : ip(0), mask(0) {}
+    IPMask(uint32_t i, uint32_t m) noexcept : ip(i), mask(m) {}
+
+    IPMask(const IPMask&) = default;
+    IPMask& operator=(const IPMask&) = default;
+    IPMask(IPMask&&) = default;
+    IPMask& operator=(IPMask&&) = default;
+
+    uint32_t ip;
+    uint32_t mask;
 };
 //-------------------------------------------------------------------------
-class USER_IPS
+class UserIPs
 {
-    friend std::ostream & operator<< (ostream & o, const USER_IPS & i);
-    //friend stringstream & operator<< (stringstream & s, const USER_IPS & i);
-    friend const USER_IPS StrToIPS(const string & ipsStr) throw(string);
-
-public:
-    USER_IPS();
-    USER_IPS(const USER_IPS &);
-    USER_IPS & operator=(const USER_IPS &);
-    const IP_MASK & operator[](int idx) const;
-    std::string GetIpStr() const;
-    bool IsIPInIPS(uint32_t ip) const;
-    bool OnlyOneIP() const;
-    int  Count() const;
-    void Add(const IP_MASK &im);
-    void Erase();
-
-private:
-    uint32_t CalcMask(unsigned int msk) const;
-    std::vector<IP_MASK> ips;
+    friend std::ostream & operator<< (std::ostream & o, const UserIPs & i);
+
+    public:
+        using ContainerType = std::vector<IPMask>;
+        using IndexType = ContainerType::size_type;
+
+        UserIPs() = default;
+
+        UserIPs(const UserIPs&) = default;
+        UserIPs& operator=(const UserIPs&) = default;
+        UserIPs(UserIPs&&) = default;
+        UserIPs& operator=(UserIPs&&) = default;
+
+        static UserIPs parse(const std::string& source);
+
+        const IPMask& operator[](IndexType idx) const noexcept { return ips[idx]; }
+        std::string toString() const noexcept;
+        bool find(uint32_t ip) const noexcept;
+        bool onlyOneIP() const noexcept;
+        bool isAnyIP() const noexcept;
+        size_t count() const noexcept { return ips.size(); }
+        void add(const IPMask& im)  noexcept{ ips.push_back(im); }
+
+    private:
+        uint32_t calcMask(unsigned int msk) const noexcept;
+        ContainerType ips;
 };
 //-------------------------------------------------------------------------
 
-//-----------------------------------------------------------------------------
-inline
-USER_IPS::USER_IPS()
-    : ips()
-{}
-//-----------------------------------------------------------------------------
-inline
-USER_IPS::USER_IPS(const USER_IPS & i)
-    : ips(i.ips)
-{}
-//-----------------------------------------------------------------------------
 inline
-USER_IPS & USER_IPS::operator=(const USER_IPS & i)
+std::string UserIPs::toString() const noexcept
 {
-ips = i.ips;
-return *this;
+    if (ips.empty())
+        return "";
+
+    if (ips[0].ip == 0)
+        return "*";
+
+    auto it = ips.begin();
+    std::string res = inet_ntostring(it->ip);
+    ++it;
+    for (; it != ips.end(); ++it)
+        res += "," + inet_ntostring(it->ip);
+    return res;
 }
 //-----------------------------------------------------------------------------
 inline
-const IP_MASK & USER_IPS::operator[](int idx) const
+uint32_t UserIPs::calcMask(unsigned int msk) const noexcept
 {
-return ips[idx];
+    if (msk > 32)
+        return 0;
+    return htonl(0xFFffFFff << (32 - msk));
 }
 //-----------------------------------------------------------------------------
 inline
-std::string USER_IPS::GetIpStr() const
+bool UserIPs::find(uint32_t ip) const noexcept
 {
-if (ips.empty())
-    {
-    return "";
-    }
+    if (ips.empty())
+        return false;
 
-if (ips[0].ip == 0)
-    {
-    return "*";
-    }
+    if (ips.front().ip == 0)
+        return true;
 
-std::vector<IP_MASK>::const_iterator it(ips.begin());
-std::stringstream s;
-s << inet_ntostring(it->ip);
-++it;
-for (; it != ips.end(); ++it)
+    for (auto it = ips.begin(); it != ips.end(); ++it)
     {
-    s << "," << inet_ntostring(it->ip);
+        const auto mask = calcMask(it->mask);
+        if ((ip & mask) == (it->ip & mask))
+            return true;
     }
-return s.str();
-}
-//-----------------------------------------------------------------------------
-inline
-int USER_IPS::Count() const
-{
-return ips.size();
-}
-//-----------------------------------------------------------------------------
-inline
-bool USER_IPS::IsIPInIPS(uint32_t ip) const
-{
-if (ips.empty())
-    {
     return false;
-    }
-
-if (ips.front().ip == 0)
-    return true;
-
-for (std::vector<IP_MASK>::const_iterator it(ips.begin()); it != ips.end(); ++it)
-    {
-    uint32_t mask(CalcMask(it->mask));
-    if ((ip & mask) == (it->ip & mask))
-        return true;
-    }
-return false;
 }
 //-----------------------------------------------------------------------------
 inline
-bool USER_IPS::OnlyOneIP() const
+bool UserIPs::onlyOneIP() const noexcept
 {
-if (ips.size() == 1 && ips.front().mask == 32)
-    return true;
+    if (ips.size() == 1 && ips.front().mask == 32 && ips.front().ip != 0)
+        return true;
 
-return false;
-}
-//-----------------------------------------------------------------------------
-inline
-uint32_t USER_IPS::CalcMask(unsigned int msk) const
-{
-if (msk > 32)
-    return 0;
-return htonl(0xFFffFFff << (32 - msk));
-}
-//-----------------------------------------------------------------------------
-inline
-void USER_IPS::Add(const IP_MASK &im)
-{
-ips.push_back(im);
+    return false;
 }
 //-----------------------------------------------------------------------------
 inline
-void USER_IPS::Erase()
+bool UserIPs::isAnyIP() const noexcept
 {
-ips.erase(ips.begin(), ips.end());
+    return !ips.empty() && ips.front().ip == 0;
 }
 //-----------------------------------------------------------------------------
 inline
-std::ostream & operator<<(std::ostream & o, const USER_IPS & i)
+std::ostream & operator<<(std::ostream& o, const UserIPs& i)
 {
-return o << i.GetIpStr();
+    return o << i.toString();
 }
 //-----------------------------------------------------------------------------
-/*inline
-stringstream & operator<<(std::stringstream & s, const USER_IPS & i)
-{
-s << i.GetIpStr();
-return s;
-}*/
-//-----------------------------------------------------------------------------
 inline
-const USER_IPS StrToIPS(const std::string & ipsStr) throw(std::string)
+UserIPs UserIPs::parse(const std::string& source)
 {
-USER_IPS ips;
-char * paddr;
-IP_MASK im;
-std::vector<std::string> ipMask;
-std::string err;
-if (ipsStr.empty())
-    {
-    return ips;
-    }
+    if (source.empty())
+        return {};
 
-if (ipsStr[0] == '*' && ipsStr.size() == 1)
+    UserIPs ips;
+    if (source[0] == '*' && source.size() == 1)
     {
-    im.ip = 0;
-    im.mask = 0;
-    ips.ips.push_back(im);
-    return ips;
+        ips.ips.push_back(IPMask());
+        return ips;
     }
 
-char * str = new char[ipsStr.size() + 1];
-strcpy(str, ipsStr.c_str());
-char * pstr = str;
-while ((paddr = strtok(pstr, ",")))
+    std::vector<std::string> ipMask;
+    char * tmp = new char[source.size() + 1];
+    strcpy(tmp, source.c_str());
+    char * pstr = tmp;
+    char * paddr = NULL;
+    while ((paddr = strtok(pstr, ",")))
     {
-    pstr = NULL;
-    ipMask.push_back(paddr);
+        pstr = NULL;
+        ipMask.push_back(paddr);
     }
 
-delete[] str;
+    delete[] tmp;
 
-for (unsigned int i = 0; i < ipMask.size(); i++)
+    for (UserIPs::IndexType i = 0; i < ipMask.size(); i++)
     {
-    char str[128];
-    char * strIp;
-    char * strMask;
-    strcpy(str, ipMask[i].c_str());
-    strIp = strtok(str, "/");
-    if (strIp == NULL)
-        {
-        err = "Incorrect IP address " + ipsStr;
-        return ips;
-        }
-    strMask = strtok(NULL, "/");
+        char str[128];
+        char * strIp;
+        char * strMask;
+        strcpy(str, ipMask[i].c_str());
+        strIp = strtok(str, "/");
+        if (strIp == NULL)
+            return ips;
+        strMask = strtok(NULL, "/");
 
-    im.ip = inet_addr(strIp);
-    if (im.ip == INADDR_NONE)
-        {
-        err = "Incorrect IP address: " + std::string(strIp);
-        return ips;
-        }
+        IPMask im;
 
-    im.mask = 32;
-    if (strMask != NULL)
-        {
-        int m = 0;
-        if (str2x(strMask, m) != 0)
-            {
-            err = "Incorrect mask: " + std::string(strMask);
+        im.ip = inet_addr(strIp);
+        if (im.ip == INADDR_NONE)
             return ips;
-            }
-        im.mask = m;
 
-        if (im.mask > 32)
-            {
-            err = "Incorrect mask: " + std::string(strMask);
-            return ips;
-            }
+        im.mask = 32;
+        if (strMask != NULL)
+        {
+            int m = 0;
+            if (str2x(strMask, m) != 0)
+                return ips;
+            im.mask = m;
 
-        if ((im.ip & ips.CalcMask(im.mask)) != im.ip)
-            {
-            err = "Address does'n match mask: " + std::string(strIp) + "/" + std::string(strMask);
-            return ips;
-            }
+            if (im.mask > 32)
+                return ips;
+
+            if ((im.ip & ips.calcMask(im.mask)) != im.ip)
+                return ips;
         }
-    ips.ips.push_back(im);
+        ips.ips.push_back(im);
     }
 
-return ips;
+    return ips;
 }
 //-------------------------------------------------------------------------
-#endif //USER_IPS_H
+}