SmartOS/Net/IPAddress.cpp

149 lines
3.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Kernel\Sys.h"
#include "IPAddress.h"
#define NET_DEBUG DEBUG
//#define NET_DEBUG 0
#if NET_DEBUG
#define net_printf debug_printf
#else
#define net_printf(format, ...)
#endif
/******************************** IPAddress ********************************/
/* IP地址 */
//const IPAddress IPAddress::Any(0, 0, 0, 0);
//const IPAddress IPAddress::Broadcast(255, 255, 255, 255);
IPAddress::IPAddress(const byte* ips)
{
Buffer((byte*)ips, 4).CopyTo(0, &Value, 4);
}
IPAddress::IPAddress(byte ip1, byte ip2, byte ip3, byte ip4)
{
Value = (ip4 << 24) + (ip3 << 16) + (ip2 << 8) + ip1;
}
IPAddress::IPAddress(const Buffer& arr)
{
arr.CopyTo(0, &Value, 4);
}
bool IPAddress::IsAny() const { return Value == 0; }
bool IPAddress::IsBroadcast() const { return Value == 0xFFFFFFFF; }
uint IPAddress::GetSubNet(const IPAddress& mask) const
{
return Value & mask.Value;
}
// 把字符串IP地址解析为IPAddress
IPAddress IPAddress::Parse(const String& ipstr)
{
auto ip = IPAddress::Any();
if(!ipstr) return ip;
// 最大长度判断 255.255.255.255
if(ipstr.Length() > 3 + 1 + 3 + 1 + 3 + 1 + 3) return ip;
if(ipstr.Contains("."))
{
// 特殊处理 0.0.0.0 和 255.255.255.255
if(ipstr == "0.0.0.0") return ip;
if(ipstr == "255.255.255.255") return IPAddress::Broadcast();
// 这里不能在Split参数直接使用字符指针隐式构造的字符串对象在这个函数之后将会被销毁
auto sp = ipstr.Split(".");
for(int i=0; i<4 && sp; i++)
{
auto item = sp.Next();
if(item.Length() == 0 || item.Length() > 3) break;
// 标准地址第一个不能是0唯一的Any例外已经在前面处理
int v = item.ToInt();
if(v < 0 || v > 255 || (i == 0 && v == 0)) break;
ip[i] = (byte)v;
// 只有完全4个都正确才直接返回
if(i == 4-1) return ip;
}
}
#if NET_DEBUG
// 只显示失败
net_printf("IPAddress::Parse %s => %08X \r\n", ipstr.GetBuffer(), ip.Value);
#endif
return IPAddress::Any();
}
const IPAddress& IPAddress::Any()
{
static const IPAddress _Any(0, 0, 0, 0);
return _Any;
}
const IPAddress& IPAddress::Broadcast()
{
static const IPAddress _Broadcast(255, 255, 255, 255);
return _Broadcast;
}
IPAddress& IPAddress::operator=(const byte* v)
{
Buffer((byte*)v, 4).CopyTo(0, &Value, 4);
return *this;
}
IPAddress& IPAddress::operator=(const Buffer& arr)
{
arr.CopyTo(0, &Value, 4);
return *this;
}
IPAddress& IPAddress::operator=(const IPAddress& addr)
{
Value = addr.Value;
return *this;
}
// 重载索引运算符[],让它可以像数组一样使用下标索引。
byte& IPAddress::operator[](int i)
{
return ((byte*)&Value)[i];
}
// 字节数组
ByteArray IPAddress::ToArray() const
{
//return ByteArray((byte*)&Value, 4);
// 要复制数据,而不是直接使用指针,那样会导致外部修改内部数据
return ByteArray(&Value, 4, true);
}
void IPAddress::CopyTo(byte* ips) const
{
if(ips) Buffer((byte*)&Value, 4).CopyTo(0, ips, 4);
}
String IPAddress::ToString() const
{
String str;
byte* ips = (byte*)&Value;
for(int i=0; i<4; i++)
{
if(i > 0) str += '.';
str += (int)ips[i];
}
return str;
}