separate PIEthernet::Address to PINetworkAddress, typedef PIEthernet::Address to PINetworkAddress and mark as deprecated
PIValueTree new attributes for File and Dir
This commit is contained in:
@@ -76,7 +76,7 @@ void PICloudClient::interrupt() {
|
|||||||
|
|
||||||
bool PICloudClient::openDevice() {
|
bool PICloudClient::openDevice() {
|
||||||
// piCoutObj << "open";// << path();
|
// piCoutObj << "open";// << path();
|
||||||
bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
|
bool op = eth.connect(PINetworkAddress::resolve(path()), false);
|
||||||
if (op) {
|
if (op) {
|
||||||
mutex_connect.lock();
|
mutex_connect.lock();
|
||||||
eth.startThreadedRead();
|
eth.startThreadedRead();
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ PIVector<PICloudServer::Client *> PICloudServer::clients() const {
|
|||||||
bool PICloudServer::openDevice() {
|
bool PICloudServer::openDevice() {
|
||||||
// piCout << "PICloudServer open device" << path();
|
// piCout << "PICloudServer open device" << path();
|
||||||
if (is_deleted) return false;
|
if (is_deleted) return false;
|
||||||
bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
|
bool op = eth.connect(PINetworkAddress::resolve(path()), false);
|
||||||
if (op) {
|
if (op) {
|
||||||
eth.startThreadedRead();
|
eth.startThreadedRead();
|
||||||
ping_timer.start(5000);
|
ping_timer.start(5000);
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ void PIBroadcast::setMulticastPort(ushort port) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIBroadcast::setMulticastAddress(const PIEthernet::Address & addr) {
|
void PIBroadcast::setMulticastAddress(const PINetworkAddress & addr) {
|
||||||
PIMutexLocker ml(mcast_mutex);
|
PIMutexLocker ml(mcast_mutex);
|
||||||
mcast_address = addr;
|
mcast_address = addr;
|
||||||
_reinit = true;
|
_reinit = true;
|
||||||
@@ -126,16 +126,16 @@ void PIBroadcast::destroyAll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
void PIBroadcast::initAll(PIVector<PINetworkAddress> al) {
|
||||||
PIMutexLocker ml(mcast_mutex);
|
PIMutexLocker ml(mcast_mutex);
|
||||||
destroyAll();
|
destroyAll();
|
||||||
_reinit = false;
|
_reinit = false;
|
||||||
prev_al = al;
|
prev_al = al;
|
||||||
al.removeAll(PIEthernet::Address("127.0.0.1"));
|
al.removeAll(PINetworkAddress("127.0.0.1"));
|
||||||
al << mcast_address;
|
al << mcast_address;
|
||||||
eth_mcast.clear();
|
eth_mcast.clear();
|
||||||
PIEthernet::InterfaceList ifaces = PIEthernet::interfaces();
|
PIEthernet::InterfaceList ifaces = PIEthernet::interfaces();
|
||||||
piForeachC(PIEthernet::Address & a, al) {
|
piForeachC(PINetworkAddress & a, al) {
|
||||||
PIEthernet * ce = 0;
|
PIEthernet * ce = 0;
|
||||||
// piCout << "mcast try" << a;
|
// piCout << "mcast try" << a;
|
||||||
if (_channels[Multicast]) {
|
if (_channels[Multicast]) {
|
||||||
@@ -166,10 +166,10 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
|||||||
ce->setName("PIMulticast_" + a.toString());
|
ce->setName("PIMulticast_" + a.toString());
|
||||||
ce->setParameters(PIEthernet::Broadcast);
|
ce->setParameters(PIEthernet::Broadcast);
|
||||||
const PIEthernet::Interface * cint = ifaces.getByAddress(a.ipString());
|
const PIEthernet::Interface * cint = ifaces.getByAddress(a.ipString());
|
||||||
PIEthernet::Address nm((cint == 0) ? "255.255.255.0" : cint->netmask);
|
PINetworkAddress nm((cint == 0) ? "255.255.255.0" : cint->netmask);
|
||||||
ce->setSendAddress(PIEthernet::getBroadcast(a, nm).ipString(), bcast_port);
|
ce->setSendAddress(PIEthernet::getBroadcast(a, nm).ipString(), bcast_port);
|
||||||
if (!_send_only) {
|
if (!_send_only) {
|
||||||
ce->setReadAddress(PIEthernet::Address(a.ip(), bcast_port));
|
ce->setReadAddress(PINetworkAddress(a.ip(), bcast_port));
|
||||||
// piCout << "bcast " << ce->readAddress() << ce->sendAddress();
|
// piCout << "bcast " << ce->readAddress() << ce->sendAddress();
|
||||||
if (ce->open()) {
|
if (ce->open()) {
|
||||||
eth_mcast << ce;
|
eth_mcast << ce;
|
||||||
@@ -260,7 +260,7 @@ void PIBroadcast::mcastRead(const uchar * data, ssize_t size) {
|
|||||||
|
|
||||||
|
|
||||||
void PIBroadcast::run() {
|
void PIBroadcast::run() {
|
||||||
PIVector<PIEthernet::Address> al = PIEthernet::allAddresses();
|
PIVector<PINetworkAddress> al = PIEthernet::allAddresses();
|
||||||
mcast_mutex.lock();
|
mcast_mutex.lock();
|
||||||
bool r = _reinit, ac = (al != prev_al);
|
bool r = _reinit, ac = (al != prev_al);
|
||||||
mcast_mutex.unlock();
|
mcast_mutex.unlock();
|
||||||
|
|||||||
@@ -104,112 +104,6 @@ PIString getSockAddr(sockaddr * s) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
PIEthernet::Address::Address(uint _ip, ushort _port) {
|
|
||||||
set(_ip, _port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIEthernet::Address::Address(const PIString & ip_port) {
|
|
||||||
set(ip_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIEthernet::Address::Address(const PIString & _ip, ushort _port) {
|
|
||||||
set(_ip, _port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString PIEthernet::Address::ipString() const {
|
|
||||||
PIString ret = PIString::fromNumber(ip_b[0]);
|
|
||||||
ret += "." + PIString::fromNumber(ip_b[1]);
|
|
||||||
ret += "." + PIString::fromNumber(ip_b[2]);
|
|
||||||
ret += "." + PIString::fromNumber(ip_b[3]);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIString PIEthernet::Address::toString() const {
|
|
||||||
return ipString() + ":" + PIString::fromNumber(port_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::Address::setIP(uint _ip) {
|
|
||||||
ip_ = _ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::Address::setIP(const PIString & _ip) {
|
|
||||||
initIP(_ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::Address::setPort(ushort _port) {
|
|
||||||
port_ = _port;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::Address::set(const PIString & ip_port) {
|
|
||||||
PIString _ip;
|
|
||||||
int p(0);
|
|
||||||
splitIPPort(ip_port, &_ip, &p);
|
|
||||||
port_ = p;
|
|
||||||
initIP(_ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::Address::set(const PIString & _ip, ushort _port) {
|
|
||||||
initIP(_ip);
|
|
||||||
port_ = _port;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::Address::set(uint _ip, ushort _port) {
|
|
||||||
ip_ = _ip;
|
|
||||||
port_ = _port;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::Address::clear() {
|
|
||||||
ip_ = 0;
|
|
||||||
port_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool PIEthernet::Address::isNull() const {
|
|
||||||
return (ip_ == 0) && (port_ == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIEthernet::Address PIEthernet::Address::resolve(const PIString & host_port) {
|
|
||||||
PIString host;
|
|
||||||
int port(0);
|
|
||||||
splitIPPort(host_port, &host, &port);
|
|
||||||
return resolve(host, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIEthernet::Address PIEthernet::Address::resolve(const PIString & host, ushort port) {
|
|
||||||
Address ret(0, port);
|
|
||||||
hostent * he = gethostbyname(host.dataAscii());
|
|
||||||
if (!he) return ret;
|
|
||||||
if (he->h_addr_list[0]) ret.setIP(*((uint *)(he->h_addr_list[0])));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::Address::splitIPPort(const PIString & ipp, PIString * _ip, int * _port) {
|
|
||||||
// piCout << "parse" << ipp;
|
|
||||||
int sp = ipp.findLast(":");
|
|
||||||
if (_ip != 0) *_ip = (sp >= 0 ? ipp.left(sp) : ipp);
|
|
||||||
if (_port != 0 && sp >= 0) *_port = ipp.right(ipp.length() - ipp.find(":") - 1).toInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIEthernet::Address::initIP(const PIString & _ip) {
|
|
||||||
ip_ = inet_addr(_ip.dataAscii());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
REGISTER_DEVICE(PIEthernet)
|
REGISTER_DEVICE(PIEthernet)
|
||||||
|
|
||||||
|
|
||||||
@@ -344,8 +238,8 @@ PIString PIEthernet::applyMask(const PIString & ip, const PIString & mask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIEthernet::Address PIEthernet::applyMask(const PIEthernet::Address & ip, const PIEthernet::Address & mask) {
|
PINetworkAddress PIEthernet::applyMask(const PINetworkAddress & ip, const PINetworkAddress & mask) {
|
||||||
Address ret(ip);
|
PINetworkAddress ret(ip);
|
||||||
ret.ip_ &= mask.ip_;
|
ret.ip_ &= mask.ip_;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -358,8 +252,8 @@ PIString PIEthernet::getBroadcast(const PIString & ip, const PIString & mask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIEthernet::Address PIEthernet::getBroadcast(const PIEthernet::Address & ip, const PIEthernet::Address & mask) {
|
PINetworkAddress PIEthernet::getBroadcast(const PINetworkAddress & ip, const PINetworkAddress & mask) {
|
||||||
Address ret(ip);
|
PINetworkAddress ret(ip);
|
||||||
ret.ip_ |= ~mask.ip_;
|
ret.ip_ |= ~mask.ip_;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -630,7 +524,7 @@ bool PIEthernet::listen(bool threaded) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIEthernet::listen(const PIEthernet::Address & addr, bool threaded) {
|
bool PIEthernet::listen(const PINetworkAddress & addr, bool threaded) {
|
||||||
setReadAddress(addr);
|
setReadAddress(addr);
|
||||||
return listen(threaded);
|
return listen(threaded);
|
||||||
}
|
}
|
||||||
@@ -645,16 +539,16 @@ bool PIEthernet::send(const void * data, int size, bool threaded) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIEthernet::send(const PIEthernet::Address & addr, const void * data, int size, bool threaded) {
|
bool PIEthernet::send(const PINetworkAddress & addr, const void * data, int size, bool threaded) {
|
||||||
addr_s = addr;
|
addr_s = addr;
|
||||||
if (threaded) {
|
if (threaded) {
|
||||||
writeThreaded(data, size);
|
writeThreaded(data, size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Address pa = addr_s;
|
PINetworkAddress pa = addr_s;
|
||||||
addr_s = addr;
|
addr_s = addr;
|
||||||
int wr = write(data, size);
|
int wr = write(data, size);
|
||||||
addr_s = pa;
|
addr_s = pa;
|
||||||
return (wr == size);
|
return (wr == size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,15 +562,15 @@ bool PIEthernet::send(const PIByteArray & data, bool threaded) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIEthernet::send(const PIEthernet::Address & addr, const PIByteArray & data, bool threaded) {
|
bool PIEthernet::send(const PINetworkAddress & addr, const PIByteArray & data, bool threaded) {
|
||||||
if (threaded) {
|
if (threaded) {
|
||||||
writeThreaded(data);
|
writeThreaded(data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Address pa = addr_s;
|
PINetworkAddress pa = addr_s;
|
||||||
addr_s = addr;
|
addr_s = addr;
|
||||||
int wr = write(data);
|
int wr = write(data);
|
||||||
addr_s = pa;
|
addr_s = pa;
|
||||||
return (wr == data.size_s());
|
return (wr == data.size_s());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1302,10 +1196,10 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIEthernet::Address PIEthernet::interfaceAddress(const PIString & interface_) {
|
PINetworkAddress PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||||
#if defined(WINDOWS) || defined(MICRO_PIP)
|
#if defined(WINDOWS) || defined(MICRO_PIP)
|
||||||
piCout << "[PIEthernet] Not implemented, use \"PIEthernet::allAddresses\" or \"PIEthernet::interfaces\" instead";
|
piCout << "[PIEthernet] Not implemented, use \"PIEthernet::allAddresses\" or \"PIEthernet::interfaces\" instead";
|
||||||
return Address();
|
return PINetworkAddress();
|
||||||
#else
|
#else
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
@@ -1314,23 +1208,23 @@ PIEthernet::Address PIEthernet::interfaceAddress(const PIString & interface_) {
|
|||||||
ioctl(s, SIOCGIFADDR, &ifr);
|
ioctl(s, SIOCGIFADDR, &ifr);
|
||||||
::close(s);
|
::close(s);
|
||||||
struct sockaddr_in * sa = (struct sockaddr_in *)&ifr.ifr_addr;
|
struct sockaddr_in * sa = (struct sockaddr_in *)&ifr.ifr_addr;
|
||||||
return Address(uint(sa->sin_addr.s_addr));
|
return PINetworkAddress(uint(sa->sin_addr.s_addr));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIVector<PIEthernet::Address> PIEthernet::allAddresses() {
|
PIVector<PINetworkAddress> PIEthernet::allAddresses() {
|
||||||
PIEthernet::InterfaceList il = interfaces();
|
PIEthernet::InterfaceList il = interfaces();
|
||||||
PIVector<Address> ret;
|
PIVector<PINetworkAddress> ret;
|
||||||
bool has_127 = false;
|
bool has_127 = false;
|
||||||
piForeachC(PIEthernet::Interface & i, il) {
|
piForeachC(PIEthernet::Interface & i, il) {
|
||||||
if (i.address == "127.0.0.1") has_127 = true;
|
if (i.address == "127.0.0.1") has_127 = true;
|
||||||
Address a(i.address);
|
PINetworkAddress a(i.address);
|
||||||
if (a.ip() == 0) continue;
|
if (a.ip() == 0) continue;
|
||||||
ret << a;
|
ret << a;
|
||||||
}
|
}
|
||||||
// piCout << "[PIEthernet::allAddresses]" << al;
|
// piCout << "[PIEthernet::allAddresses]" << al;
|
||||||
if (!has_127) ret << Address("127.0.0.1");
|
if (!has_127) ret << PINetworkAddress("127.0.0.1");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#define PIETHERNET_H
|
#define PIETHERNET_H
|
||||||
|
|
||||||
#include "piiodevice.h"
|
#include "piiodevice.h"
|
||||||
#include "pitimer.h"
|
#include "pinetworkaddress.h"
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
struct
|
struct
|
||||||
@@ -63,74 +63,7 @@ public:
|
|||||||
DisonnectOnTimeout /** Disconnect TCP connection on read timeout expired. Disabled by default */ = 0x20
|
DisonnectOnTimeout /** Disconnect TCP connection on read timeout expired. Disabled by default */ = 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef ::PINetworkAddress Address DEPRECATEDM("use PINetworkAddress instead");
|
||||||
//! \brief IPv4 network address, IP and port
|
|
||||||
class PIP_EXPORT Address {
|
|
||||||
friend class PIEthernet;
|
|
||||||
|
|
||||||
public:
|
|
||||||
//! Contructs %Address with binary representation of IP and port
|
|
||||||
Address(uint ip = 0, ushort port = 0);
|
|
||||||
|
|
||||||
//! Contructs %Address with string representation "i.i.i.i:p"
|
|
||||||
Address(const PIString & ip_port);
|
|
||||||
|
|
||||||
//! Contructs %Address with IP string representation "i.i.i.i" and port
|
|
||||||
Address(const PIString & ip, ushort port);
|
|
||||||
|
|
||||||
//! Returns binary IP
|
|
||||||
uint ip() const { return ip_; }
|
|
||||||
|
|
||||||
//! Returns port
|
|
||||||
ushort port() const { return port_; }
|
|
||||||
|
|
||||||
//! Returns string IP
|
|
||||||
PIString ipString() const;
|
|
||||||
|
|
||||||
//! Returns string representation of IP and port "i.i.i.i:p"
|
|
||||||
PIString toString() const;
|
|
||||||
|
|
||||||
//! Set address IP
|
|
||||||
void setIP(uint ip);
|
|
||||||
|
|
||||||
//! Set address IP
|
|
||||||
void setIP(const PIString & ip);
|
|
||||||
|
|
||||||
//! Set address port
|
|
||||||
void setPort(ushort port);
|
|
||||||
|
|
||||||
//! Set address IP and port, "i.i.i.i:p"
|
|
||||||
void set(const PIString & ip_port);
|
|
||||||
|
|
||||||
//! Set address IP and port, "i.i.i.i"
|
|
||||||
void set(const PIString & ip, ushort port);
|
|
||||||
|
|
||||||
//! Set address binary IP and port
|
|
||||||
void set(uint ip, ushort port);
|
|
||||||
|
|
||||||
//! Set IP and port to 0
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
//! Returns if IP and port is 0
|
|
||||||
bool isNull() const;
|
|
||||||
|
|
||||||
//! Resolve hostname "host:port" and return it address or null address on error
|
|
||||||
static Address resolve(const PIString & host_port);
|
|
||||||
|
|
||||||
//! Resolve hostname "host" with port "port" and return it address or null address on error
|
|
||||||
static Address resolve(const PIString & host, ushort port);
|
|
||||||
|
|
||||||
static void splitIPPort(const PIString & ipp, PIString * ip, int * port);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initIP(const PIString & _ip);
|
|
||||||
union {
|
|
||||||
uint ip_;
|
|
||||||
uchar ip_b[4];
|
|
||||||
};
|
|
||||||
ushort port_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//! Contructs %PIEthernet with type "type", read address "ip_port" and parameters "params"
|
//! Contructs %PIEthernet with type "type", read address "ip_port" and parameters "params"
|
||||||
explicit PIEthernet(Type type,
|
explicit PIEthernet(Type type,
|
||||||
@@ -154,7 +87,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Set read address
|
//! Set read address
|
||||||
void setReadAddress(const Address & addr) {
|
void setReadAddress(const PINetworkAddress & addr) {
|
||||||
addr_r = addr;
|
addr_r = addr;
|
||||||
setPath(addr_r.toString());
|
setPath(addr_r.toString());
|
||||||
}
|
}
|
||||||
@@ -179,7 +112,7 @@ public:
|
|||||||
void setSendAddress(const PIString & ip_port) { addr_s.set(ip_port); }
|
void setSendAddress(const PIString & ip_port) { addr_s.set(ip_port); }
|
||||||
|
|
||||||
//! Set send address
|
//! Set send address
|
||||||
void setSendAddress(const Address & addr) { addr_s = addr; }
|
void setSendAddress(const PINetworkAddress & addr) { addr_s = addr; }
|
||||||
|
|
||||||
//! Set send IP
|
//! Set send IP
|
||||||
void setSendIP(const PIString & ip) { addr_s.setIP(ip); }
|
void setSendIP(const PIString & ip) { addr_s.setIP(ip); }
|
||||||
@@ -189,7 +122,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Returns read address in format "i.i.i.i:p"
|
//! Returns read address in format "i.i.i.i:p"
|
||||||
Address readAddress() const { return addr_r; }
|
PINetworkAddress readAddress() const { return addr_r; }
|
||||||
|
|
||||||
//! Returns read IP
|
//! Returns read IP
|
||||||
PIString readIP() const { return addr_r.ipString(); }
|
PIString readIP() const { return addr_r.ipString(); }
|
||||||
@@ -199,7 +132,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Returns send address in format "i.i.i.i:p"
|
//! Returns send address in format "i.i.i.i:p"
|
||||||
Address sendAddress() const { return addr_s; }
|
PINetworkAddress sendAddress() const { return addr_s; }
|
||||||
|
|
||||||
//! Returns send IP
|
//! Returns send IP
|
||||||
PIString sendIP() const { return addr_s.ipString(); }
|
PIString sendIP() const { return addr_s.ipString(); }
|
||||||
@@ -209,7 +142,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//! Returns address of last received UDP packet in format "i.i.i.i:p"
|
//! Returns address of last received UDP packet in format "i.i.i.i:p"
|
||||||
Address lastReadAddress() const { return addr_lr; }
|
PINetworkAddress lastReadAddress() const { return addr_lr; }
|
||||||
|
|
||||||
//! Returns IP of last received UDP packet
|
//! Returns IP of last received UDP packet
|
||||||
PIString lastReadIP() const { return addr_lr.ipString(); }
|
PIString lastReadIP() const { return addr_lr.ipString(); }
|
||||||
@@ -287,7 +220,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Connect to TCP server with address "addr". Use only for TCP_Client
|
//! Connect to TCP server with address "addr". Use only for TCP_Client
|
||||||
bool connect(const Address & addr, bool threaded = true) {
|
bool connect(const PINetworkAddress & addr, bool threaded = true) {
|
||||||
setPath(addr.toString());
|
setPath(addr.toString());
|
||||||
return connect(threaded);
|
return connect(threaded);
|
||||||
}
|
}
|
||||||
@@ -303,13 +236,13 @@ public:
|
|||||||
bool listen(bool threaded = false);
|
bool listen(bool threaded = false);
|
||||||
|
|
||||||
//! Start listen for incoming TCP connections on address "ip":"port". Use only for TCP_Server
|
//! Start listen for incoming TCP connections on address "ip":"port". Use only for TCP_Server
|
||||||
bool listen(const PIString & ip, int port, bool threaded = false) { return listen(PIEthernet::Address(ip, port), threaded); }
|
bool listen(const PIString & ip, int port, bool threaded = false) { return listen(PINetworkAddress(ip, port), threaded); }
|
||||||
|
|
||||||
//! Start listen for incoming TCP connections on address "ip_port". Use only for TCP_Server
|
//! Start listen for incoming TCP connections on address "ip_port". Use only for TCP_Server
|
||||||
bool listen(const PIString & ip_port, bool threaded = false) { return listen(PIEthernet::Address(ip_port), threaded); }
|
bool listen(const PIString & ip_port, bool threaded = false) { return listen(PINetworkAddress(ip_port), threaded); }
|
||||||
|
|
||||||
//! Start listen for incoming TCP connections on address "addr". Use only for TCP_Server
|
//! Start listen for incoming TCP connections on address "addr". Use only for TCP_Server
|
||||||
bool listen(const Address & addr, bool threaded = false);
|
bool listen(const PINetworkAddress & addr, bool threaded = false);
|
||||||
|
|
||||||
PIEthernet * client(int index) { return clients_[index]; }
|
PIEthernet * client(int index) { return clients_[index]; }
|
||||||
int clientsCount() const { return clients_.size_s(); }
|
int clientsCount() const { return clients_.size_s(); }
|
||||||
@@ -321,32 +254,32 @@ public:
|
|||||||
|
|
||||||
//! Send data "data" with size "size" to address "ip":"port"
|
//! Send data "data" with size "size" to address "ip":"port"
|
||||||
bool send(const PIString & ip, int port, const void * data, int size, bool threaded = false) {
|
bool send(const PIString & ip, int port, const void * data, int size, bool threaded = false) {
|
||||||
return send(PIEthernet::Address(ip, port), data, size, threaded);
|
return send(PINetworkAddress(ip, port), data, size, threaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Send data "data" with size "size" to address "ip_port"
|
//! Send data "data" with size "size" to address "ip_port"
|
||||||
bool send(const PIString & ip_port, const void * data, int size, bool threaded = false) {
|
bool send(const PIString & ip_port, const void * data, int size, bool threaded = false) {
|
||||||
return send(PIEthernet::Address(ip_port), data, size, threaded);
|
return send(PINetworkAddress(ip_port), data, size, threaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Send data "data" with size "size" to address "addr"
|
//! Send data "data" with size "size" to address "addr"
|
||||||
bool send(const Address & addr, const void * data, int size, bool threaded = false);
|
bool send(const PINetworkAddress & addr, const void * data, int size, bool threaded = false);
|
||||||
|
|
||||||
//! Send data "data" to address \a sendAddress() for UDP or \a readAddress() for TCP_Client
|
//! Send data "data" to address \a sendAddress() for UDP or \a readAddress() for TCP_Client
|
||||||
bool send(const PIByteArray & data, bool threaded = false);
|
bool send(const PIByteArray & data, bool threaded = false);
|
||||||
|
|
||||||
//! Send data "data" to address "ip":"port" for UDP
|
//! Send data "data" to address "ip":"port" for UDP
|
||||||
bool send(const PIString & ip, int port, const PIByteArray & data, bool threaded = false) {
|
bool send(const PIString & ip, int port, const PIByteArray & data, bool threaded = false) {
|
||||||
return send(PIEthernet::Address(ip, port), data, threaded);
|
return send(PINetworkAddress(ip, port), data, threaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Send data "data" to address "ip_port" for UDP
|
//! Send data "data" to address "ip_port" for UDP
|
||||||
bool send(const PIString & ip_port, const PIByteArray & data, bool threaded = false) {
|
bool send(const PIString & ip_port, const PIByteArray & data, bool threaded = false) {
|
||||||
return send(PIEthernet::Address(ip_port), data, threaded);
|
return send(PINetworkAddress(ip_port), data, threaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Send data "data" to address "addr" for UDP
|
//! Send data "data" to address "addr" for UDP
|
||||||
bool send(const Address & addr, const PIByteArray & data, bool threaded = false);
|
bool send(const PINetworkAddress & addr, const PIByteArray & data, bool threaded = false);
|
||||||
|
|
||||||
bool canWrite() const override { return mode() & WriteOnly; }
|
bool canWrite() const override { return mode() & WriteOnly; }
|
||||||
|
|
||||||
@@ -460,17 +393,17 @@ public:
|
|||||||
//! Returns all system network interfaces
|
//! Returns all system network interfaces
|
||||||
static InterfaceList interfaces();
|
static InterfaceList interfaces();
|
||||||
|
|
||||||
static PIEthernet::Address interfaceAddress(const PIString & interface_);
|
static PINetworkAddress interfaceAddress(const PIString & interface_);
|
||||||
|
|
||||||
//! Returns all system network IP addresses
|
//! Returns all system network IP addresses
|
||||||
static PIVector<PIEthernet::Address> allAddresses();
|
static PIVector<PINetworkAddress> allAddresses();
|
||||||
|
|
||||||
static PIString macFromBytes(const PIByteArray & mac);
|
static PIString macFromBytes(const PIByteArray & mac);
|
||||||
static PIByteArray macToBytes(const PIString & mac);
|
static PIByteArray macToBytes(const PIString & mac);
|
||||||
static PIString applyMask(const PIString & ip, const PIString & mask);
|
static PIString applyMask(const PIString & ip, const PIString & mask);
|
||||||
static Address applyMask(const Address & ip, const Address & mask);
|
static PINetworkAddress applyMask(const PINetworkAddress & ip, const PINetworkAddress & mask);
|
||||||
static PIString getBroadcast(const PIString & ip, const PIString & mask);
|
static PIString getBroadcast(const PIString & ip, const PIString & mask);
|
||||||
static Address getBroadcast(const Address & ip, const Address & mask);
|
static PINetworkAddress getBroadcast(const PINetworkAddress & ip, const PINetworkAddress & mask);
|
||||||
|
|
||||||
//! \events
|
//! \events
|
||||||
//! \{
|
//! \{
|
||||||
@@ -540,7 +473,7 @@ protected:
|
|||||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||||
int sock, sock_s;
|
int sock, sock_s;
|
||||||
std::atomic_bool connected_, connecting_, listen_threaded, server_bounded;
|
std::atomic_bool connected_, connecting_, listen_threaded, server_bounded;
|
||||||
mutable Address addr_r, addr_s, addr_lr;
|
mutable PINetworkAddress addr_r, addr_s, addr_lr;
|
||||||
Type eth_type;
|
Type eth_type;
|
||||||
PIThread server_thread_;
|
PIThread server_thread_;
|
||||||
PIMutex clients_mutex;
|
PIMutex clients_mutex;
|
||||||
@@ -580,19 +513,5 @@ inline bool operator==(const PIEthernet::Interface & v0, const PIEthernet::Inter
|
|||||||
inline bool operator!=(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {
|
inline bool operator!=(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {
|
||||||
return (v0.name != v1.name || v0.address != v1.address || v0.netmask != v1.netmask);
|
return (v0.name != v1.name || v0.address != v1.address || v0.netmask != v1.netmask);
|
||||||
}
|
}
|
||||||
inline PICout operator<<(PICout s, const PIEthernet::Address & v) {
|
|
||||||
s.space();
|
|
||||||
s.saveAndSetControls(0);
|
|
||||||
s << "Address(" << v.toString() << ")";
|
|
||||||
s.restoreControls();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator==(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {
|
|
||||||
return (v0.ip() == v1.ip() && v0.port() == v1.port());
|
|
||||||
}
|
|
||||||
inline bool operator!=(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {
|
|
||||||
return (v0.ip() != v1.ip() || v0.port() != v1.port());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PIETHERNET_H
|
#endif // PIETHERNET_H
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ void PIPeer::PeerData::setDist(int dist) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIPeer::PeerInfo::PeerAddress::PeerAddress(const PIEthernet::Address & a, const PIEthernet::Address & m): address(a), netmask(m) {
|
PIPeer::PeerInfo::PeerAddress::PeerAddress(const PINetworkAddress & a, const PINetworkAddress & m): address(a), netmask(m) {
|
||||||
ping = -1.;
|
ping = -1.;
|
||||||
wait_ping = false;
|
wait_ping = false;
|
||||||
last_ping = PISystemTime::current(true);
|
last_ping = PISystemTime::current(true);
|
||||||
@@ -150,9 +150,9 @@ void PIPeer::PeerInfo::destroy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIEthernet::Address PIPeer::PeerInfo::fastestAddress() const {
|
PINetworkAddress PIPeer::PeerInfo::fastestAddress() const {
|
||||||
double mp = -1.;
|
double mp = -1.;
|
||||||
PIEthernet::Address ret;
|
PINetworkAddress ret;
|
||||||
piForeachC(PeerAddress & a, addresses) {
|
piForeachC(PeerAddress & a, addresses) {
|
||||||
if (a.ping <= 0.) continue;
|
if (a.ping <= 0.) continue;
|
||||||
if ((mp < 0) || (mp > a.ping)) {
|
if ((mp < 0) || (mp > a.ping)) {
|
||||||
@@ -356,7 +356,7 @@ void PIPeer::initMBcasts(PIStringList al) {
|
|||||||
eth_tcp_cli.startThreadedRead();
|
eth_tcp_cli.startThreadedRead();
|
||||||
if (eths_mcast.isEmpty() && eths_bcast.isEmpty() && !eth_lo.isOpened())
|
if (eths_mcast.isEmpty() && eths_bcast.isEmpty() && !eth_lo.isOpened())
|
||||||
piCoutObj << "Warning! Can`t find suitable network interface for multicast receive, check for exists at least one interface with "
|
piCoutObj << "Warning! Can`t find suitable network interface for multicast receive, check for exists at least one interface with "
|
||||||
"multicasting enabled!";
|
"multicasting enabled!";
|
||||||
// piCoutObj << "initMBcasts ok";
|
// piCoutObj << "initMBcasts ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,7 +474,7 @@ bool PIPeer::dataRead(const uchar * readed, ssize_t size) {
|
|||||||
eth_mutex.lock();
|
eth_mutex.lock();
|
||||||
// piCout << "dataRead lock";
|
// piCout << "dataRead lock";
|
||||||
if (type == 5) { // ping request
|
if (type == 5) { // ping request
|
||||||
PIEthernet::Address addr;
|
PINetworkAddress addr;
|
||||||
PISystemTime time;
|
PISystemTime time;
|
||||||
ba >> to >> from >> addr >> time;
|
ba >> to >> from >> addr >> time;
|
||||||
// piCout << "ping request" << to << from << addr;
|
// piCout << "ping request" << to << from << addr;
|
||||||
@@ -497,7 +497,7 @@ bool PIPeer::dataRead(const uchar * readed, ssize_t size) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (type == 6) { // ping request
|
if (type == 6) { // ping request
|
||||||
PIEthernet::Address addr;
|
PINetworkAddress addr;
|
||||||
PISystemTime time, ptime, ctime = PISystemTime::current(true);
|
PISystemTime time, ptime, ctime = PISystemTime::current(true);
|
||||||
ba >> to >> from >> addr >> time;
|
ba >> to >> from >> addr >> time;
|
||||||
// piCout << "ping reply" << to << from << addr;
|
// piCout << "ping reply" << to << from << addr;
|
||||||
@@ -725,7 +725,7 @@ bool PIPeer::mbcastRead(const uchar * data, ssize_t size) {
|
|||||||
|
|
||||||
|
|
||||||
bool PIPeer::sendToNeighbour(PIPeer::PeerInfo * peer, const PIByteArray & ba) {
|
bool PIPeer::sendToNeighbour(PIPeer::PeerInfo * peer, const PIByteArray & ba) {
|
||||||
PIEthernet::Address addr = peer->fastestAddress();
|
PINetworkAddress addr = peer->fastestAddress();
|
||||||
// piCout << "[PIPeer] sendToNeighbour" << peer->name << addr << ba.size_s() << "bytes ...";
|
// piCout << "[PIPeer] sendToNeighbour" << peer->name << addr << ba.size_s() << "bytes ...";
|
||||||
send_mutex.lock();
|
send_mutex.lock();
|
||||||
bool ok = eth_send.send(addr, ba);
|
bool ok = eth_send.send(addr, ba);
|
||||||
@@ -1025,9 +1025,9 @@ void PIPeer::initNetwork() {
|
|||||||
piMSleep(100);
|
piMSleep(100);
|
||||||
// piCoutObj << self_info.addresses.size();
|
// piCoutObj << self_info.addresses.size();
|
||||||
self_info.addresses.clear();
|
self_info.addresses.clear();
|
||||||
PIVector<PIEthernet::Address> al = PIEthernet::allAddresses();
|
PIVector<PINetworkAddress> al = PIEthernet::allAddresses();
|
||||||
PIStringList sl;
|
PIStringList sl;
|
||||||
for (const PIEthernet::Address & a: al) {
|
for (const PINetworkAddress & a: al) {
|
||||||
sl << a.ipString();
|
sl << a.ipString();
|
||||||
}
|
}
|
||||||
initEths(sl);
|
initEths(sl);
|
||||||
|
|||||||
@@ -53,11 +53,10 @@ public:
|
|||||||
~PeerInfo() {}
|
~PeerInfo() {}
|
||||||
|
|
||||||
struct PIP_EXPORT PeerAddress {
|
struct PIP_EXPORT PeerAddress {
|
||||||
PeerAddress(const PIEthernet::Address & a = PIEthernet::Address(),
|
PeerAddress(const PINetworkAddress & a = PINetworkAddress(), const PINetworkAddress & m = PINetworkAddress("255.255.255.0"));
|
||||||
const PIEthernet::Address & m = PIEthernet::Address("255.255.255.0"));
|
|
||||||
bool isAvailable() const { return ping > 0; }
|
bool isAvailable() const { return ping > 0; }
|
||||||
PIEthernet::Address address;
|
PINetworkAddress address;
|
||||||
PIEthernet::Address netmask;
|
PINetworkAddress netmask;
|
||||||
double ping; // ms
|
double ping; // ms
|
||||||
bool wait_ping;
|
bool wait_ping;
|
||||||
PISystemTime last_ping;
|
PISystemTime last_ping;
|
||||||
@@ -70,7 +69,7 @@ public:
|
|||||||
|
|
||||||
bool isNeighbour() const { return dist == 0; }
|
bool isNeighbour() const { return dist == 0; }
|
||||||
int ping() const;
|
int ping() const;
|
||||||
PIEthernet::Address fastestAddress() const;
|
PINetworkAddress fastestAddress() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addNeighbour(const PIString & n) {
|
void addNeighbour(const PIString & n) {
|
||||||
|
|||||||
@@ -77,10 +77,10 @@ public:
|
|||||||
ushort multicastPort() const { return mcast_address.port(); }
|
ushort multicastPort() const { return mcast_address.port(); }
|
||||||
|
|
||||||
//! Set multicast address to \"addr\" and queue to reinit
|
//! Set multicast address to \"addr\" and queue to reinit
|
||||||
void setMulticastAddress(const PIEthernet::Address & addr);
|
void setMulticastAddress(const PINetworkAddress & addr);
|
||||||
|
|
||||||
//! Returns multicast address
|
//! Returns multicast address
|
||||||
PIEthernet::Address multicastAddress() const { return mcast_address; }
|
PINetworkAddress multicastAddress() const { return mcast_address; }
|
||||||
|
|
||||||
|
|
||||||
//! Set broadcast port to \"port\" and queue to reinit
|
//! Set broadcast port to \"port\" and queue to reinit
|
||||||
@@ -136,15 +136,15 @@ protected:
|
|||||||
private:
|
private:
|
||||||
EVENT_HANDLER2(void, mcastRead, const uchar *, data, ssize_t, size);
|
EVENT_HANDLER2(void, mcastRead, const uchar *, data, ssize_t, size);
|
||||||
void destroyAll();
|
void destroyAll();
|
||||||
void initAll(PIVector<PIEthernet::Address> al);
|
void initAll(PIVector<PINetworkAddress> al);
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|
||||||
Channels _channels;
|
Channels _channels;
|
||||||
PIEthernet::Address mcast_address;
|
PINetworkAddress mcast_address;
|
||||||
PIMutex mcast_mutex;
|
PIMutex mcast_mutex;
|
||||||
PIVector<PIEthernet *> eth_mcast;
|
PIVector<PIEthernet *> eth_mcast;
|
||||||
PIEthernet * eth_lo;
|
PIEthernet * eth_lo;
|
||||||
PIVector<PIEthernet::Address> prev_al;
|
PIVector<PINetworkAddress> prev_al;
|
||||||
ushort lo_port, bcast_port;
|
ushort lo_port, bcast_port;
|
||||||
int lo_pcnt;
|
int lo_pcnt;
|
||||||
bool _started, _send_only, _reinit;
|
bool _started, _send_only, _reinit;
|
||||||
|
|||||||
165
libs/main/types/pinetworkaddress.cpp
Normal file
165
libs/main/types/pinetworkaddress.cpp
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Network address
|
||||||
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pinetworkaddress.h"
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
#ifdef QNX
|
||||||
|
# include <netdb.h>
|
||||||
|
#else
|
||||||
|
# ifdef WINDOWS
|
||||||
|
# include <winsock2.h>
|
||||||
|
# else
|
||||||
|
# include <netdb.h>
|
||||||
|
# ifdef LWIP
|
||||||
|
# include <lwip/sockets.h>
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
|
//! \class PISystemTime pisystemtime.h
|
||||||
|
//! \details
|
||||||
|
//! \~english \section PISystemTime_sec0 Synopsis
|
||||||
|
//! \~russian \section PISystemTime_sec0 Краткий обзор
|
||||||
|
//! \~english
|
||||||
|
//! This class provide arithmetic functions for POSIX system time.
|
||||||
|
//! This time represents as seconds and nanosecons in integer formats.
|
||||||
|
//! You can take current system time with function \a PISystemTime::current(),
|
||||||
|
//! compare times, sum or subtract two times, convert time to/from
|
||||||
|
//! seconds, milliseconds, microseconds or nanoseconds.
|
||||||
|
//!
|
||||||
|
//! \~russian
|
||||||
|
//! Этот класс предоставляет арифметику для системного времени в формате POSIX.
|
||||||
|
//! Это время представлено в виде целочисленных секунд и наносекунд.
|
||||||
|
//! Можно взять текущее время с помощью метода \a PISystemTime::current(),
|
||||||
|
//! сравнивать, суммировать и вычитать времена, преобразовывать в/из
|
||||||
|
//! секунд, миллисекунд, микросекунд и наносекунд.
|
||||||
|
//!
|
||||||
|
//! \~english \section PISystemTime_sec1 Example
|
||||||
|
//! \~russian \section PISystemTime_sec1 Пример
|
||||||
|
//! \~\snippet pitimer.cpp system_time
|
||||||
|
//!
|
||||||
|
|
||||||
|
|
||||||
|
PINetworkAddress::PINetworkAddress(uint _ip, ushort _port) {
|
||||||
|
set(_ip, _port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PINetworkAddress::PINetworkAddress(const PIString & ip_port) {
|
||||||
|
set(ip_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PINetworkAddress::PINetworkAddress(const PIString & _ip, ushort _port) {
|
||||||
|
set(_ip, _port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PINetworkAddress::ipString() const {
|
||||||
|
PIString ret = PIString::fromNumber(ip_b[0]);
|
||||||
|
ret += "." + PIString::fromNumber(ip_b[1]);
|
||||||
|
ret += "." + PIString::fromNumber(ip_b[2]);
|
||||||
|
ret += "." + PIString::fromNumber(ip_b[3]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PINetworkAddress::toString() const {
|
||||||
|
return ipString() + ":" + PIString::fromNumber(port_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PINetworkAddress::setIP(uint _ip) {
|
||||||
|
ip_ = _ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PINetworkAddress::setIP(const PIString & _ip) {
|
||||||
|
initIP(_ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PINetworkAddress::setPort(ushort _port) {
|
||||||
|
port_ = _port;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PINetworkAddress::set(const PIString & ip_port) {
|
||||||
|
PIString _ip;
|
||||||
|
int p(0);
|
||||||
|
splitIPPort(ip_port, &_ip, &p);
|
||||||
|
port_ = p;
|
||||||
|
initIP(_ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PINetworkAddress::set(const PIString & _ip, ushort _port) {
|
||||||
|
initIP(_ip);
|
||||||
|
port_ = _port;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PINetworkAddress::set(uint _ip, ushort _port) {
|
||||||
|
ip_ = _ip;
|
||||||
|
port_ = _port;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PINetworkAddress::clear() {
|
||||||
|
ip_ = 0;
|
||||||
|
port_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PINetworkAddress::isNull() const {
|
||||||
|
return (ip_ == 0) && (port_ == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PINetworkAddress PINetworkAddress::resolve(const PIString & host_port) {
|
||||||
|
PIString host;
|
||||||
|
int port(0);
|
||||||
|
splitIPPort(host_port, &host, &port);
|
||||||
|
return resolve(host, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PINetworkAddress PINetworkAddress::resolve(const PIString & host, ushort port) {
|
||||||
|
PINetworkAddress ret(0, port);
|
||||||
|
hostent * he = gethostbyname(host.dataAscii());
|
||||||
|
if (!he) return ret;
|
||||||
|
if (he->h_addr_list[0]) ret.setIP(*((uint *)(he->h_addr_list[0])));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PINetworkAddress::splitIPPort(const PIString & ipp, PIString * _ip, int * _port) {
|
||||||
|
// piCout << "parse" << ipp;
|
||||||
|
int sp = ipp.findLast(":");
|
||||||
|
if (_ip != 0) *_ip = (sp >= 0 ? ipp.left(sp) : ipp);
|
||||||
|
if (_port != 0 && sp >= 0) *_port = ipp.right(ipp.length() - ipp.find(":") - 1).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PINetworkAddress::initIP(const PIString & _ip) {
|
||||||
|
ip_ = inet_addr(_ip.dataAscii());
|
||||||
|
}
|
||||||
125
libs/main/types/pinetworkaddress.h
Normal file
125
libs/main/types/pinetworkaddress.h
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*! \file pinetworkaddress.h
|
||||||
|
* \ingroup Types
|
||||||
|
* \~\brief
|
||||||
|
* \~english Network address
|
||||||
|
* \~russian Сетевой адрес
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Network address
|
||||||
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PINETWORKADDRESS_H
|
||||||
|
#define PINETWORKADDRESS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "pistring.h"
|
||||||
|
|
||||||
|
|
||||||
|
//! \ingroup Types
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Network address, IP and port.
|
||||||
|
//! \~russian Сетевой адрес, IP и порт.
|
||||||
|
class PIP_EXPORT PINetworkAddress {
|
||||||
|
friend class PIEthernet;
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! Contructs %Address with binary representation of IP and port
|
||||||
|
PINetworkAddress(uint ip = 0, ushort port = 0);
|
||||||
|
|
||||||
|
//! Contructs %Address with string representation "i.i.i.i:p"
|
||||||
|
PINetworkAddress(const PIString & ip_port);
|
||||||
|
|
||||||
|
//! Contructs %Address with IP string representation "i.i.i.i" and port
|
||||||
|
PINetworkAddress(const PIString & ip, ushort port);
|
||||||
|
|
||||||
|
//! Returns binary IP
|
||||||
|
uint ip() const { return ip_; }
|
||||||
|
|
||||||
|
//! Returns port
|
||||||
|
ushort port() const { return port_; }
|
||||||
|
|
||||||
|
//! Returns string IP
|
||||||
|
PIString ipString() const;
|
||||||
|
|
||||||
|
//! Returns string representation of IP and port "i.i.i.i:p"
|
||||||
|
PIString toString() const;
|
||||||
|
|
||||||
|
//! Set address IP
|
||||||
|
void setIP(uint ip);
|
||||||
|
|
||||||
|
//! Set address IP
|
||||||
|
void setIP(const PIString & ip);
|
||||||
|
|
||||||
|
//! Set address port
|
||||||
|
void setPort(ushort port);
|
||||||
|
|
||||||
|
//! Set address IP and port, "i.i.i.i:p"
|
||||||
|
void set(const PIString & ip_port);
|
||||||
|
|
||||||
|
//! Set address IP and port, "i.i.i.i"
|
||||||
|
void set(const PIString & ip, ushort port);
|
||||||
|
|
||||||
|
//! Set address binary IP and port
|
||||||
|
void set(uint ip, ushort port);
|
||||||
|
|
||||||
|
//! Set IP and port to 0
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
//! Returns if IP and port is 0
|
||||||
|
bool isNull() const;
|
||||||
|
|
||||||
|
//! Resolve hostname "host:port" and return it address or null address on error
|
||||||
|
static PINetworkAddress resolve(const PIString & host_port);
|
||||||
|
|
||||||
|
//! Resolve hostname "host" with port "port" and return it address or null address on error
|
||||||
|
static PINetworkAddress resolve(const PIString & host, ushort port);
|
||||||
|
|
||||||
|
static void splitIPPort(const PIString & ipp, PIString * ip, int * port);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initIP(const PIString & _ip);
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint ip_;
|
||||||
|
uchar ip_b[4];
|
||||||
|
};
|
||||||
|
ushort port_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool operator==(const PINetworkAddress & v0, const PINetworkAddress & v1) {
|
||||||
|
return (v0.ip() == v1.ip() && v0.port() == v1.port());
|
||||||
|
}
|
||||||
|
inline bool operator!=(const PINetworkAddress & v0, const PINetworkAddress & v1) {
|
||||||
|
return (v0.ip() != v1.ip() || v0.port() != v1.port());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! \relatesalso PICout
|
||||||
|
//! \~english \brief Output operator to PICout
|
||||||
|
//! \~russian \brief Оператор вывода в PICout
|
||||||
|
inline PICout operator<<(PICout s, const PINetworkAddress & v) {
|
||||||
|
s.space();
|
||||||
|
s.saveAndSetControls(0);
|
||||||
|
s << "Address(" << v.toString() << ")";
|
||||||
|
s.restoreControls();
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PINETWORKADDRESS_H
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
#include "pibitarray.h"
|
#include "pibitarray.h"
|
||||||
#include "pibytearray.h"
|
#include "pibytearray.h"
|
||||||
#include "piflags.h"
|
#include "piflags.h"
|
||||||
|
#include "pinetworkaddress.h"
|
||||||
#include "pipropertystorage.h"
|
#include "pipropertystorage.h"
|
||||||
#include "pitime.h"
|
#include "pitime.h"
|
||||||
#include "pivaluetree.h"
|
#include "pivaluetree.h"
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ const char PIValueTree::Attribute::decimals [] = "decimals" ;
|
|||||||
const char PIValueTree::Attribute::prefix [] = "prefix" ;
|
const char PIValueTree::Attribute::prefix [] = "prefix" ;
|
||||||
const char PIValueTree::Attribute::suffix [] = "suffix" ;
|
const char PIValueTree::Attribute::suffix [] = "suffix" ;
|
||||||
const char PIValueTree::Attribute::style [] = "style" ;
|
const char PIValueTree::Attribute::style [] = "style" ;
|
||||||
|
const char PIValueTree::Attribute::filter [] = "filter" ;
|
||||||
|
const char PIValueTree::Attribute::absolutePath [] = "absolutePath" ;
|
||||||
|
const char PIValueTree::Attribute::onlyExisting [] = "onlyExisting" ;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ public:
|
|||||||
static const char prefix [];
|
static const char prefix [];
|
||||||
static const char suffix [];
|
static const char suffix [];
|
||||||
static const char style [];
|
static const char style [];
|
||||||
|
static const char filter [];
|
||||||
|
static const char absolutePath [];
|
||||||
|
static const char onlyExisting [];
|
||||||
//static constexpr char attribute[] = "";
|
//static constexpr char attribute[] = "";
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -157,8 +157,8 @@ void PIVariant::setValueFromString(const PIString & v) {
|
|||||||
setValue(PIVariantTypes::Color::fromString(v));
|
setValue(PIVariantTypes::Color::fromString(v));
|
||||||
} break;
|
} break;
|
||||||
case PIVariant::pivIODevice: {
|
case PIVariant::pivIODevice: {
|
||||||
setValue(PIVariantTypes::IODevice());
|
setValue(PIVariantTypes::IODevice()); // TODO
|
||||||
} break; // TODO
|
} break;
|
||||||
case PIVariant::pivPoint: {
|
case PIVariant::pivPoint: {
|
||||||
PIStringList l = v.split(';');
|
PIStringList l = v.split(';');
|
||||||
if (l.size() >= 2) setValue(PIPointd(l[0].toDouble(), l[1].toDouble()));
|
if (l.size() >= 2) setValue(PIPointd(l[0].toDouble(), l[1].toDouble()));
|
||||||
@@ -171,6 +171,9 @@ void PIVariant::setValueFromString(const PIString & v) {
|
|||||||
PIStringList l = v.split(';');
|
PIStringList l = v.split(';');
|
||||||
if (l.size() >= 4) setValue(PILined(l[0].toDouble(), l[1].toDouble(), l[2].toDouble(), l[3].toDouble()));
|
if (l.size() >= 4) setValue(PILined(l[0].toDouble(), l[1].toDouble(), l[2].toDouble(), l[3].toDouble()));
|
||||||
} break;
|
} break;
|
||||||
|
case PIVariant::pivNetworkAddress: {
|
||||||
|
setValue(PINetworkAddress(v));
|
||||||
|
} break;
|
||||||
case PIVariant::pivCustom: {
|
case PIVariant::pivCustom: {
|
||||||
#ifdef CUSTOM_PIVARIANT
|
#ifdef CUSTOM_PIVARIANT
|
||||||
__PIVariantInfo__ * vi = __PIVariantInfoStorage__::get()->map->value(__PIVariantFunctions__<PIString>::typeIDHelper());
|
__PIVariantInfo__ * vi = __PIVariantInfoStorage__::get()->map->value(__PIVariantFunctions__<PIString>::typeIDHelper());
|
||||||
@@ -252,6 +255,7 @@ PIVariant::Type PIVariant::typeFromName(const PIString & tname) {
|
|||||||
if (s == "pimathvectord" || s == "vector") return PIVariant::pivMathVector;
|
if (s == "pimathvectord" || s == "vector") return PIVariant::pivMathVector;
|
||||||
if (s == "pimathmatrixd" || s == "matrix") return PIVariant::pivMathMatrix;
|
if (s == "pimathmatrixd" || s == "matrix") return PIVariant::pivMathMatrix;
|
||||||
if (s == "pilined" || s == "line") return PIVariant::pivLine;
|
if (s == "pilined" || s == "line") return PIVariant::pivLine;
|
||||||
|
if (s == "pinetworkaddress" || s == "networkaddress" || s == "ip") return PIVariant::pivNetworkAddress;
|
||||||
return PIVariant::pivInvalid;
|
return PIVariant::pivInvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +295,7 @@ PIVariant::Type PIVariant::typeFromID(uint type_id) {
|
|||||||
if (type_id == typeID<PIMathVectord>()) return PIVariant::pivMathVector;
|
if (type_id == typeID<PIMathVectord>()) return PIVariant::pivMathVector;
|
||||||
if (type_id == typeID<PIMathMatrixd>()) return PIVariant::pivMathMatrix;
|
if (type_id == typeID<PIMathMatrixd>()) return PIVariant::pivMathMatrix;
|
||||||
if (type_id == typeID<PILined>()) return PIVariant::pivLine;
|
if (type_id == typeID<PILined>()) return PIVariant::pivLine;
|
||||||
|
if (type_id == typeID<PINetworkAddress>()) return PIVariant::pivNetworkAddress;
|
||||||
#ifdef CUSTOM_PIVARIANT
|
#ifdef CUSTOM_PIVARIANT
|
||||||
if (__PIVariantInfoStorage__::get()->map->contains(type_id)) return PIVariant::pivCustom;
|
if (__PIVariantInfoStorage__::get()->map->contains(type_id)) return PIVariant::pivCustom;
|
||||||
#endif
|
#endif
|
||||||
@@ -309,38 +314,39 @@ uint PIVariant::typeIDFromName(const PIString & tname) {
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
uint PIVariant::typeIDFromType(Type type) {
|
uint PIVariant::typeIDFromType(Type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case (PIVariant::pivBool ): return typeID<bool >();
|
case (PIVariant::pivBool ): return typeID<bool >();
|
||||||
case (PIVariant::pivChar ): return typeID<char >();
|
case (PIVariant::pivChar ): return typeID<char >();
|
||||||
case (PIVariant::pivShort ): return typeID<short >();
|
case (PIVariant::pivShort ): return typeID<short >();
|
||||||
case (PIVariant::pivInt ): return typeID<int >();
|
case (PIVariant::pivInt ): return typeID<int >();
|
||||||
case (PIVariant::pivLLong ): return typeID<llong >();
|
case (PIVariant::pivLLong ): return typeID<llong >();
|
||||||
case (PIVariant::pivUChar ): return typeID<uchar >();
|
case (PIVariant::pivUChar ): return typeID<uchar >();
|
||||||
case (PIVariant::pivUShort ): return typeID<ushort >();
|
case (PIVariant::pivUShort ): return typeID<ushort >();
|
||||||
case (PIVariant::pivUInt ): return typeID<uint >();
|
case (PIVariant::pivUInt ): return typeID<uint >();
|
||||||
case (PIVariant::pivULLong ): return typeID<ullong >();
|
case (PIVariant::pivULLong ): return typeID<ullong >();
|
||||||
case (PIVariant::pivFloat ): return typeID<float >();
|
case (PIVariant::pivFloat ): return typeID<float >();
|
||||||
case (PIVariant::pivDouble ): return typeID<double >();
|
case (PIVariant::pivDouble ): return typeID<double >();
|
||||||
case (PIVariant::pivLDouble ): return typeID<ldouble >();
|
case (PIVariant::pivLDouble ): return typeID<ldouble >();
|
||||||
case (PIVariant::pivComplexd ): return typeID<complexd >();
|
case (PIVariant::pivComplexd ): return typeID<complexd >();
|
||||||
case (PIVariant::pivComplexld ): return typeID<complexld >();
|
case (PIVariant::pivComplexld ): return typeID<complexld >();
|
||||||
case (PIVariant::pivBitArray ): return typeID<PIBitArray >();
|
case (PIVariant::pivBitArray ): return typeID<PIBitArray >();
|
||||||
case (PIVariant::pivByteArray ): return typeID<PIByteArray >();
|
case (PIVariant::pivByteArray ): return typeID<PIByteArray >();
|
||||||
case (PIVariant::pivString ): return typeID<PIString >();
|
case (PIVariant::pivString ): return typeID<PIString >();
|
||||||
case (PIVariant::pivStringList): return typeID<PIStringList >();
|
case (PIVariant::pivStringList ): return typeID<PIStringList >();
|
||||||
case (PIVariant::pivTime ): return typeID<PITime >();
|
case (PIVariant::pivTime ): return typeID<PITime >();
|
||||||
case (PIVariant::pivDate ): return typeID<PIDate >();
|
case (PIVariant::pivDate ): return typeID<PIDate >();
|
||||||
case (PIVariant::pivDateTime ): return typeID<PIDateTime >();
|
case (PIVariant::pivDateTime ): return typeID<PIDateTime >();
|
||||||
case (PIVariant::pivSystemTime): return typeID<PISystemTime >();
|
case (PIVariant::pivSystemTime ): return typeID<PISystemTime >();
|
||||||
case (PIVariant::pivEnum ): return typeID<PIVariantTypes::Enum >();
|
case (PIVariant::pivEnum ): return typeID<PIVariantTypes::Enum >();
|
||||||
case (PIVariant::pivFile ): return typeID<PIVariantTypes::File >();
|
case (PIVariant::pivFile ): return typeID<PIVariantTypes::File >();
|
||||||
case (PIVariant::pivDir ): return typeID<PIVariantTypes::Dir >();
|
case (PIVariant::pivDir ): return typeID<PIVariantTypes::Dir >();
|
||||||
case (PIVariant::pivColor ): return typeID<PIVariantTypes::Color >();
|
case (PIVariant::pivColor ): return typeID<PIVariantTypes::Color >();
|
||||||
case (PIVariant::pivIODevice ): return typeID<PIVariantTypes::IODevice >();
|
case (PIVariant::pivIODevice ): return typeID<PIVariantTypes::IODevice >();
|
||||||
case (PIVariant::pivPoint ): return typeID<PIPointd >();
|
case (PIVariant::pivPoint ): return typeID<PIPointd >();
|
||||||
case (PIVariant::pivRect ): return typeID<PIRectd >();
|
case (PIVariant::pivRect ): return typeID<PIRectd >();
|
||||||
case (PIVariant::pivMathVector): return typeID<PIMathVectord >();
|
case (PIVariant::pivMathVector ): return typeID<PIMathVectord >();
|
||||||
case (PIVariant::pivMathMatrix): return typeID<PIMathMatrixd >();
|
case (PIVariant::pivMathMatrix ): return typeID<PIMathMatrixd >();
|
||||||
case (PIVariant::pivLine ): return typeID<PILined >();
|
case (PIVariant::pivLine ): return typeID<PILined >();
|
||||||
|
case (PIVariant::pivNetworkAddress): return typeID<PINetworkAddress >();
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -452,6 +458,8 @@ PIString PIVariant::typeName(PIVariant::Type type) {
|
|||||||
case PIVariant::pivIODevice: return "IODevice";
|
case PIVariant::pivIODevice: return "IODevice";
|
||||||
case PIVariant::pivPoint: return "Point";
|
case PIVariant::pivPoint: return "Point";
|
||||||
case PIVariant::pivRect: return "Rect";
|
case PIVariant::pivRect: return "Rect";
|
||||||
|
case PIVariant::pivLine: return "Line";
|
||||||
|
case PIVariant::pivNetworkAddress: return "NetworkAddress";
|
||||||
case PIVariant::pivMathVector: return "Vector";
|
case PIVariant::pivMathVector: return "Vector";
|
||||||
case PIVariant::pivMathMatrix: return "Matrix";
|
case PIVariant::pivMathMatrix: return "Matrix";
|
||||||
case PIVariant::pivCustom: return "Custom";
|
case PIVariant::pivCustom: return "Custom";
|
||||||
@@ -1284,6 +1292,7 @@ PISystemTime PIVariant::toSystemTime() const {
|
|||||||
//! In case of BitArray or ByteArray types returns number of bits/bytes. \n
|
//! In case of BitArray or ByteArray types returns number of bits/bytes. \n
|
||||||
//! In case of Time, Date or DateTime types returns toString() of this values. \n
|
//! In case of Time, Date or DateTime types returns toString() of this values. \n
|
||||||
//! In case of SystemTime types returns second and nanoseconds of time
|
//! In case of SystemTime types returns second and nanoseconds of time
|
||||||
|
//! In case of NetworkAddress types returns "i.i.i.i:p"
|
||||||
//! ("(PISystemTime::seconds s, PISystemTime::nanoseconds ns)"). \n
|
//! ("(PISystemTime::seconds s, PISystemTime::nanoseconds ns)"). \n
|
||||||
//! In case of other types returns \b "".
|
//! In case of other types returns \b "".
|
||||||
//!
|
//!
|
||||||
@@ -1294,6 +1303,7 @@ PISystemTime PIVariant::toSystemTime() const {
|
|||||||
//! Для типов BitArray или ByteArray возвращает количество бит/байт. \n
|
//! Для типов BitArray или ByteArray возвращает количество бит/байт. \n
|
||||||
//! Для типов Time, Date или DateTime возвращает toString(). \n
|
//! Для типов Time, Date или DateTime возвращает toString(). \n
|
||||||
//! Для типов SystemTime возвращает секунды и наносекунды в формате "(s, ns)".
|
//! Для типов SystemTime возвращает секунды и наносекунды в формате "(s, ns)".
|
||||||
|
//! Для типов NetworkAddress возвращает "i.i.i.i:p"
|
||||||
//! Для остальных типов возвращает \b "".
|
//! Для остальных типов возвращает \b "".
|
||||||
//!
|
//!
|
||||||
PIString PIVariant::toString() const {
|
PIString PIVariant::toString() const {
|
||||||
@@ -1427,6 +1437,11 @@ PIString PIVariant::toString() const {
|
|||||||
return PIString::fromNumber(r.p0.x) + ";" + PIString::fromNumber(r.p0.y) + ";" + PIString::fromNumber(r.p1.x) + ";" +
|
return PIString::fromNumber(r.p0.x) + ";" + PIString::fromNumber(r.p0.y) + ";" + PIString::fromNumber(r.p1.x) + ";" +
|
||||||
PIString::fromNumber(r.p1.y);
|
PIString::fromNumber(r.p1.y);
|
||||||
} break;
|
} break;
|
||||||
|
case PIVariant::pivNetworkAddress: {
|
||||||
|
PINetworkAddress r;
|
||||||
|
ba >> r;
|
||||||
|
return r.toString();
|
||||||
|
} break;
|
||||||
case PIVariant::pivCustom: return getAsValue<PIString>(*this);
|
case PIVariant::pivCustom: return getAsValue<PIString>(*this);
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
@@ -1788,6 +1803,37 @@ PILined PIVariant::toLine() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! \~\brief
|
||||||
|
//! \~english Returns variant content as PINetworkAddress
|
||||||
|
//! \~russian Возвращает содержимое как PINetworkAddress
|
||||||
|
//!
|
||||||
|
//! \~\details
|
||||||
|
//! \~english
|
||||||
|
//! In case of NetworkAddress type returns address. \n
|
||||||
|
//! In case of String type returns address from "i.i.i.i:p". \n
|
||||||
|
//! In case of other types returns empty PINetworkAddress.
|
||||||
|
//!
|
||||||
|
//! \~russian
|
||||||
|
//! Для типа NetworkAddress возвращает адрес. \n
|
||||||
|
//! Для типа String возвращает адрес из формата "i.i.i.i:p". \n
|
||||||
|
//! Для остальных типов возвращает пустой PINetworkAddress.
|
||||||
|
//!
|
||||||
|
PINetworkAddress PIVariant::toNetworkAddress() const {
|
||||||
|
PIByteArray ba(_content);
|
||||||
|
if (_type == PIVariant::pivString) {
|
||||||
|
PIString r;
|
||||||
|
ba >> r;
|
||||||
|
return PINetworkAddress(r);
|
||||||
|
}
|
||||||
|
if (_type == PIVariant::pivNetworkAddress) {
|
||||||
|
PINetworkAddress r;
|
||||||
|
ba >> r;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
return PINetworkAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \~\brief
|
//! \~\brief
|
||||||
//! \~english Returns variant content as math vector
|
//! \~english Returns variant content as math vector
|
||||||
//! \~russian Возвращает содержимое как вектор
|
//! \~russian Возвращает содержимое как вектор
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include "pidatetime.h"
|
#include "pidatetime.h"
|
||||||
#include "piline.h"
|
#include "piline.h"
|
||||||
#include "pimathmatrix.h"
|
#include "pimathmatrix.h"
|
||||||
|
#include "pinetworkaddress.h"
|
||||||
#include "pipoint.h"
|
#include "pipoint.h"
|
||||||
#include "pirect.h"
|
#include "pirect.h"
|
||||||
#include "pivarianttypes.h"
|
#include "pivarianttypes.h"
|
||||||
@@ -265,6 +266,7 @@ public:
|
|||||||
pivMathVector /** PIMathVector<double> */,
|
pivMathVector /** PIMathVector<double> */,
|
||||||
pivMathMatrix /** PIMathMatrix<double> */,
|
pivMathMatrix /** PIMathMatrix<double> */,
|
||||||
pivLine /** PILine<double> */,
|
pivLine /** PILine<double> */,
|
||||||
|
pivNetworkAddress /** PINetworkAddress */,
|
||||||
pivCustom /** \~english Custom \~russian Свой тип */ = 0xFF
|
pivCustom /** \~english Custom \~russian Свой тип */ = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -280,127 +282,131 @@ public:
|
|||||||
//! \~russian Перемещающий конструктор.
|
//! \~russian Перемещающий конструктор.
|
||||||
PIVariant(PIVariant && v);
|
PIVariant(PIVariant && v);
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from string
|
//! \~english Constructs %PIVariant from string.
|
||||||
//! \~russian Создает %PIVariant из строки.
|
//! \~russian Создает %PIVariant из строки.
|
||||||
PIVariant(const char * v) { initType(PIString(v)); }
|
PIVariant(const char * v) { initType(PIString(v)); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from boolean
|
//! \~english Constructs %PIVariant from boolean.
|
||||||
//! \~russian Создает %PIVariant из логического значения.
|
//! \~russian Создает %PIVariant из логического значения.
|
||||||
PIVariant(const bool v) { initType(v); }
|
PIVariant(const bool v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from char
|
//! \~english Constructs %PIVariant from char.
|
||||||
//! \~russian Создает %PIVariant из символа.
|
//! \~russian Создает %PIVariant из символа.
|
||||||
PIVariant(const char v) { initType(v); }
|
PIVariant(const char v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from integer
|
//! \~english Constructs %PIVariant from integer.
|
||||||
//! \~russian Создает %PIVariant из целого числа.
|
//! \~russian Создает %PIVariant из целого числа.
|
||||||
PIVariant(const uchar v) { initType(v); }
|
PIVariant(const uchar v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from integer
|
//! \~english Constructs %PIVariant from integer.
|
||||||
//! \~russian Создает %PIVariant из целого числа.
|
//! \~russian Создает %PIVariant из целого числа.
|
||||||
PIVariant(const short v) { initType(v); }
|
PIVariant(const short v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from integer
|
//! \~english Constructs %PIVariant from integer.
|
||||||
//! \~russian Создает %PIVariant из целого числа.
|
//! \~russian Создает %PIVariant из целого числа.
|
||||||
PIVariant(const ushort v) { initType(v); }
|
PIVariant(const ushort v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from integer
|
//! \~english Constructs %PIVariant from integer.
|
||||||
//! \~russian Создает %PIVariant из целого числа.
|
//! \~russian Создает %PIVariant из целого числа.
|
||||||
PIVariant(const int & v) { initType(v); }
|
PIVariant(const int & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from integer
|
//! \~english Constructs %PIVariant from integer.
|
||||||
//! \~russian Создает %PIVariant из целого числа.
|
//! \~russian Создает %PIVariant из целого числа.
|
||||||
PIVariant(const uint & v) { initType(v); }
|
PIVariant(const uint & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from integer
|
//! \~english Constructs %PIVariant from integer.
|
||||||
//! \~russian Создает %PIVariant из целого числа.
|
//! \~russian Создает %PIVariant из целого числа.
|
||||||
PIVariant(const llong & v) { initType(v); }
|
PIVariant(const llong & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from integer
|
//! \~english Constructs %PIVariant from integer.
|
||||||
//! \~russian Создает %PIVariant из целого числа.
|
//! \~russian Создает %PIVariant из целого числа.
|
||||||
PIVariant(const ullong & v) { initType(v); }
|
PIVariant(const ullong & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from float
|
//! \~english Constructs %PIVariant from float.
|
||||||
//! \~russian Создает %PIVariant из вещественного числа.
|
//! \~russian Создает %PIVariant из вещественного числа.
|
||||||
PIVariant(const float & v) { initType(v); }
|
PIVariant(const float & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from double
|
//! \~english Constructs %PIVariant from double.
|
||||||
//! \~russian Создает %PIVariant из вещественного числа.
|
//! \~russian Создает %PIVariant из вещественного числа.
|
||||||
PIVariant(const double & v) { initType(v); }
|
PIVariant(const double & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from long double
|
//! \~english Constructs %PIVariant from long double.
|
||||||
//! \~russian Создает %PIVariant из вещественного числа.
|
//! \~russian Создает %PIVariant из вещественного числа.
|
||||||
PIVariant(const ldouble & v) { initType(v); }
|
PIVariant(const ldouble & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from bit array
|
//! \~english Constructs %PIVariant from bit array.
|
||||||
//! \~russian Создает %PIVariant из массива битов.
|
//! \~russian Создает %PIVariant из массива битов.
|
||||||
PIVariant(const PIBitArray & v) { initType(v); }
|
PIVariant(const PIBitArray & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from byte array
|
//! \~english Constructs %PIVariant from byte array.
|
||||||
//! \~russian Создает %PIVariant из массива байтов.
|
//! \~russian Создает %PIVariant из массива байтов.
|
||||||
PIVariant(const PIByteArray & v) { initType(v); }
|
PIVariant(const PIByteArray & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from string
|
//! \~english Constructs %PIVariant from string.
|
||||||
//! \~russian Создает %PIVariant из строки.
|
//! \~russian Создает %PIVariant из строки.
|
||||||
PIVariant(const PIString & v) { initType(v); }
|
PIVariant(const PIString & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from strings list
|
//! \~english Constructs %PIVariant from strings list.
|
||||||
//! \~russian Создает %PIVariant из массива строк.
|
//! \~russian Создает %PIVariant из массива строк.
|
||||||
PIVariant(const PIStringList & v) { initType(v); }
|
PIVariant(const PIStringList & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from time
|
//! \~english Constructs %PIVariant from time.
|
||||||
//! \~russian Создает %PIVariant из времени.
|
//! \~russian Создает %PIVariant из времени.
|
||||||
PIVariant(const PITime & v) { initType(v); }
|
PIVariant(const PITime & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from date
|
//! \~english Constructs %PIVariant from date.
|
||||||
//! \~russian Создает %PIVariant из даты.
|
//! \~russian Создает %PIVariant из даты.
|
||||||
PIVariant(const PIDate & v) { initType(v); }
|
PIVariant(const PIDate & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from date and time
|
//! \~english Constructs %PIVariant from date and time.
|
||||||
//! \~russian Создает %PIVariant из даты и времени.
|
//! \~russian Создает %PIVariant из даты и времени.
|
||||||
PIVariant(const PIDateTime & v) { initType(v); }
|
PIVariant(const PIDateTime & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from system time
|
//! \~english Constructs %PIVariant from system time.
|
||||||
//! \~russian Создает %PIVariant из системного времени.
|
//! \~russian Создает %PIVariant из системного времени.
|
||||||
PIVariant(const PISystemTime & v) { initType(v); }
|
PIVariant(const PISystemTime & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from enum
|
//! \~english Constructs %PIVariant from enum.
|
||||||
//! \~russian Создает %PIVariant из перечисления.
|
//! \~russian Создает %PIVariant из перечисления.
|
||||||
PIVariant(const PIVariantTypes::Enum & v) { initType(v); }
|
PIVariant(const PIVariantTypes::Enum & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from file
|
//! \~english Constructs %PIVariant from file.
|
||||||
//! \~russian Создает %PIVariant из файла.
|
//! \~russian Создает %PIVariant из файла.
|
||||||
PIVariant(const PIVariantTypes::File & v) { initType(v); }
|
PIVariant(const PIVariantTypes::File & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from dir
|
//! \~english Constructs %PIVariant from dir.
|
||||||
//! \~russian Создает %PIVariant из директории.
|
//! \~russian Создает %PIVariant из директории.
|
||||||
PIVariant(const PIVariantTypes::Dir & v) { initType(v); }
|
PIVariant(const PIVariantTypes::Dir & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from color
|
//! \~english Constructs %PIVariant from color.
|
||||||
//! \~russian Создает %PIVariant из цвета.
|
//! \~russian Создает %PIVariant из цвета.
|
||||||
PIVariant(const PIVariantTypes::Color & v) { initType(v); }
|
PIVariant(const PIVariantTypes::Color & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from IODevice
|
//! \~english Constructs %PIVariant from IODevice.
|
||||||
//! \~russian Создает %PIVariant из IODevice.
|
//! \~russian Создает %PIVariant из IODevice.
|
||||||
PIVariant(const PIVariantTypes::IODevice & v) { initType(v); }
|
PIVariant(const PIVariantTypes::IODevice & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from point
|
//! \~english Constructs %PIVariant from point.
|
||||||
//! \~russian Создает %PIVariant из точки.
|
//! \~russian Создает %PIVariant из точки.
|
||||||
PIVariant(const PIPointd & v) { initType(v); }
|
PIVariant(const PIPointd & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from rect
|
//! \~english Constructs %PIVariant from rect.
|
||||||
//! \~russian Создает %PIVariant из прямоугольника.
|
//! \~russian Создает %PIVariant из прямоугольника.
|
||||||
PIVariant(const PIRectd & v) { initType(v); }
|
PIVariant(const PIRectd & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from line
|
//! \~english Constructs %PIVariant from line.
|
||||||
//! \~russian Создает %PIVariant из линии.
|
//! \~russian Создает %PIVariant из линии.
|
||||||
PIVariant(const PILined & v) { initType(v); }
|
PIVariant(const PILined & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from MathVector
|
//! \~english Constructs %PIVariant from PINetworkAddress.
|
||||||
|
//! \~russian Создает %PIVariant из PINetworkAddress.
|
||||||
|
PIVariant(const PINetworkAddress & v) { initType(v); }
|
||||||
|
|
||||||
|
//! \~english Constructs %PIVariant from MathVector.
|
||||||
//! \~russian Создает %PIVariant из MathVector.
|
//! \~russian Создает %PIVariant из MathVector.
|
||||||
PIVariant(const PIMathVectord & v) { initType(v); }
|
PIVariant(const PIMathVectord & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Constructs %PIVariant from MathMatrix
|
//! \~english Constructs %PIVariant from MathMatrix.
|
||||||
//! \~russian Создает %PIVariant из MathMatrix.
|
//! \~russian Создает %PIVariant из MathMatrix.
|
||||||
PIVariant(const PIMathMatrixd & v) { initType(v); }
|
PIVariant(const PIMathMatrixd & v) { initType(v); }
|
||||||
|
|
||||||
@@ -526,6 +532,10 @@ public:
|
|||||||
//! \~russian Устанавливает значение и тип из вектора
|
//! \~russian Устанавливает значение и тип из вектора
|
||||||
void setValue(const PIMathVectord & v) { initType(v); }
|
void setValue(const PIMathVectord & v) { initType(v); }
|
||||||
|
|
||||||
|
//! \~english Set variant content and type to PINetworkAddress
|
||||||
|
//! \~russian Устанавливает значение и тип из PINetworkAddress
|
||||||
|
void setValue(const PINetworkAddress & v) { initType(v); }
|
||||||
|
|
||||||
//! \~english Set variant content and type to math matrix
|
//! \~english Set variant content and type to math matrix
|
||||||
//! \~russian Устанавливает значение и тип из матрицы
|
//! \~russian Устанавливает значение и тип из матрицы
|
||||||
void setValue(const PIMathMatrixd & v) { initType(v); }
|
void setValue(const PIMathMatrixd & v) { initType(v); }
|
||||||
@@ -558,6 +568,7 @@ public:
|
|||||||
PIPointd toPoint() const;
|
PIPointd toPoint() const;
|
||||||
PIRectd toRect() const;
|
PIRectd toRect() const;
|
||||||
PILined toLine() const;
|
PILined toLine() const;
|
||||||
|
PINetworkAddress toNetworkAddress() const;
|
||||||
PIMathVectord toMathVector() const;
|
PIMathVectord toMathVector() const;
|
||||||
PIMathMatrixd toMathMatrix() const;
|
PIMathMatrixd toMathMatrix() const;
|
||||||
|
|
||||||
@@ -788,6 +799,13 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \~english Assign operator.
|
||||||
|
//! \~russian Оператор присваивания.
|
||||||
|
PIVariant & operator=(const PINetworkAddress & v) {
|
||||||
|
setValue(v);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
//! \~english Assign operator.
|
//! \~english Assign operator.
|
||||||
//! \~russian Оператор присваивания.
|
//! \~russian Оператор присваивания.
|
||||||
PIVariant & operator=(const PIMathVectord & v) {
|
PIVariant & operator=(const PIMathVectord & v) {
|
||||||
@@ -1000,6 +1018,7 @@ template<> inline PIVariantTypes::IODevice PIVariant::value() const {return toIO
|
|||||||
template<> inline PIPointd PIVariant::value() const {return toPoint();}
|
template<> inline PIPointd PIVariant::value() const {return toPoint();}
|
||||||
template<> inline PIRectd PIVariant::value() const {return toRect();}
|
template<> inline PIRectd PIVariant::value() const {return toRect();}
|
||||||
template<> inline PILined PIVariant::value() const {return toLine();}
|
template<> inline PILined PIVariant::value() const {return toLine();}
|
||||||
|
template<> inline PINetworkAddress PIVariant::value() const {return toNetworkAddress();}
|
||||||
template<> inline PIVariant PIVariant::value() const {return *this;}
|
template<> inline PIVariant PIVariant::value() const {return *this;}
|
||||||
|
|
||||||
template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);}
|
template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);}
|
||||||
@@ -1030,6 +1049,7 @@ template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::IODevice
|
|||||||
template<> inline PIVariant PIVariant::fromValue(const PIPointd & v) {return PIVariant(v);}
|
template<> inline PIVariant PIVariant::fromValue(const PIPointd & v) {return PIVariant(v);}
|
||||||
template<> inline PIVariant PIVariant::fromValue(const PIRectd & v) {return PIVariant(v);}
|
template<> inline PIVariant PIVariant::fromValue(const PIRectd & v) {return PIVariant(v);}
|
||||||
template<> inline PIVariant PIVariant::fromValue(const PILined & v) {return PIVariant(v);}
|
template<> inline PIVariant PIVariant::fromValue(const PILined & v) {return PIVariant(v);}
|
||||||
|
template<> inline PIVariant PIVariant::fromValue(const PINetworkAddress & v) {return PIVariant(v);}
|
||||||
template<> inline PIVariant PIVariant::fromValue(const PIMathVectord & v) {return PIVariant(v);}
|
template<> inline PIVariant PIVariant::fromValue(const PIMathVectord & v) {return PIVariant(v);}
|
||||||
template<> inline PIVariant PIVariant::fromValue(const PIMathMatrixd & v) {return PIVariant(v);}
|
template<> inline PIVariant PIVariant::fromValue(const PIMathMatrixd & v) {return PIVariant(v);}
|
||||||
template<> inline PIVariant PIVariant::fromValue(const PIVariant & v) {return PIVariant(v);}
|
template<> inline PIVariant PIVariant::fromValue(const PIVariant & v) {return PIVariant(v);}
|
||||||
@@ -1062,6 +1082,7 @@ template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::IODevice>()
|
|||||||
template<> inline PIVariant::Type PIVariant::getType<PIPointd>() {return PIVariant::pivPoint;}
|
template<> inline PIVariant::Type PIVariant::getType<PIPointd>() {return PIVariant::pivPoint;}
|
||||||
template<> inline PIVariant::Type PIVariant::getType<PIRectd>() {return PIVariant::pivRect;}
|
template<> inline PIVariant::Type PIVariant::getType<PIRectd>() {return PIVariant::pivRect;}
|
||||||
template<> inline PIVariant::Type PIVariant::getType<PILined>() {return PIVariant::pivLine;}
|
template<> inline PIVariant::Type PIVariant::getType<PILined>() {return PIVariant::pivLine;}
|
||||||
|
template<> inline PIVariant::Type PIVariant::getType<PINetworkAddress>() {return PIVariant::pivNetworkAddress;}
|
||||||
template<> inline PIVariant::Type PIVariant::getType<PIMathVectord>() {return PIVariant::pivMathVector;}
|
template<> inline PIVariant::Type PIVariant::getType<PIMathVectord>() {return PIVariant::pivMathVector;}
|
||||||
template<> inline PIVariant::Type PIVariant::getType<PIMathMatrixd>() {return PIVariant::pivMathMatrix;}
|
template<> inline PIVariant::Type PIVariant::getType<PIMathMatrixd>() {return PIVariant::pivMathMatrix;}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@@ -1094,6 +1115,7 @@ REGISTER_VARIANT(PIVariantTypes::IODevice)
|
|||||||
REGISTER_VARIANT(PIPointd)
|
REGISTER_VARIANT(PIPointd)
|
||||||
REGISTER_VARIANT(PIRectd)
|
REGISTER_VARIANT(PIRectd)
|
||||||
REGISTER_VARIANT(PILined)
|
REGISTER_VARIANT(PILined)
|
||||||
|
REGISTER_VARIANT(PINetworkAddress)
|
||||||
REGISTER_VARIANT(PIMathVectord)
|
REGISTER_VARIANT(PIMathVectord)
|
||||||
REGISTER_VARIANT(PIMathMatrixd)
|
REGISTER_VARIANT(PIMathMatrixd)
|
||||||
REGISTER_VARIANT(PIVariantMap);
|
REGISTER_VARIANT(PIVariantMap);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "piscreentiles.h"
|
#include "piscreentiles.h"
|
||||||
|
|
||||||
|
|
||||||
DispatcherServer::DispatcherServer(PIEthernet::Address addr): eth(PIEthernet::TCP_Server) {
|
DispatcherServer::DispatcherServer(PINetworkAddress addr): eth(PIEthernet::TCP_Server) {
|
||||||
client_gid = 0;
|
client_gid = 0;
|
||||||
max_connections = 1000;
|
max_connections = 1000;
|
||||||
eth.setParameter(PIEthernet::ReuseAddress);
|
eth.setParameter(PIEthernet::ReuseAddress);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class DispatcherServer: public PIObject {
|
|||||||
PIOBJECT(DispatcherServer)
|
PIOBJECT(DispatcherServer)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DispatcherServer(PIEthernet::Address addr);
|
DispatcherServer(PINetworkAddress addr);
|
||||||
~DispatcherServer();
|
~DispatcherServer();
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
|
|||||||
@@ -65,9 +65,9 @@ int main(int argc, char * argv[]) {
|
|||||||
usage();
|
usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
PIEthernet::Address addr = PIEthernet::Address("0.0.0.0", 10101);
|
PINetworkAddress addr = PINetworkAddress("0.0.0.0", 10101);
|
||||||
|
|
||||||
PIString conf_path = confDir();
|
PIString conf_path = confDir();
|
||||||
PIDir::make(conf_path);
|
PIDir::make(conf_path);
|
||||||
conf_path += "/picloud.conf";
|
conf_path += "/picloud.conf";
|
||||||
uint max_connections = 1000;
|
uint max_connections = 1000;
|
||||||
|
|||||||
Reference in New Issue
Block a user