diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 06b9d2c09..c7cc5418a 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -317,6 +317,7 @@ namespace Nz { inline SharedString(); inline SharedString(unsigned int strSize); + inline SharedString(unsigned int strSize, unsigned int strCapacity); unsigned int capacity; unsigned int size; diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index 656a56121..49157777f 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -23,12 +23,20 @@ namespace Nz } inline String::SharedString::SharedString(unsigned int strSize) : - capacity(strSize), + capacity(strSize), size(strSize), string(new char[strSize + 1]) { string[strSize] = '\0'; } + + inline String::SharedString::SharedString(unsigned int strSize, unsigned int strCapacity) : + capacity(strCapacity), + size(strSize), + string(new char[strCapacity + 1]) + { + string[strSize] = '\0'; + } } namespace std diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 5481d22a9..21c96dde4 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -30,8 +30,9 @@ namespace Nz NetProtocol_Any, NetProtocol_IPv4, NetProtocol_IPv6, + NetProtocol_Unknown, - NetProtocol_Max = NetProtocol_IPv6 + NetProtocol_Max = NetProtocol_Unknown }; enum SocketError @@ -71,8 +72,9 @@ namespace Nz SocketType_Raw, SocketType_TCP, SocketType_UDP, + SocketType_Unknown, - SocketType_Max = SocketType_UDP + SocketType_Max = SocketType_Unknown }; } diff --git a/include/Nazara/Network/IpAddress.hpp b/include/Nazara/Network/IpAddress.hpp index c9fa5c5b9..32def1031 100644 --- a/include/Nazara/Network/IpAddress.hpp +++ b/include/Nazara/Network/IpAddress.hpp @@ -89,10 +89,9 @@ namespace Nz struct HostnameInfo { IpAddress address; + NetProtocol protocol; + SocketType socketType; String canonicalName; - int flags; - int family; //< TODO: NetProtocol - int socketType; //< TODO: SocketType }; } diff --git a/include/Nazara/Network/IpAddress.inl b/include/Nazara/Network/IpAddress.inl index c9aab3065..425fa6fee 100644 --- a/include/Nazara/Network/IpAddress.inl +++ b/include/Nazara/Network/IpAddress.inl @@ -118,6 +118,7 @@ namespace Nz switch (first.m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: break; case NetProtocol_IPv4: @@ -167,6 +168,7 @@ namespace Nz switch (first.m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: break; case NetProtocol_IPv4: diff --git a/include/Nazara/Network/TcpServer.inl b/include/Nazara/Network/TcpServer.inl index 42092b41b..5350a58ee 100644 --- a/include/Nazara/Network/TcpServer.inl +++ b/include/Nazara/Network/TcpServer.inl @@ -31,11 +31,13 @@ namespace Nz inline SocketState TcpServer::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize) { NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO + NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); IpAddress any; switch (protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: NazaraInternalError("Invalid protocol Any at this point"); return SocketState_NotConnected; diff --git a/include/Nazara/Network/UdpSocket.inl b/include/Nazara/Network/UdpSocket.inl index 4a75da130..9ad4d067b 100644 --- a/include/Nazara/Network/UdpSocket.inl +++ b/include/Nazara/Network/UdpSocket.inl @@ -30,6 +30,7 @@ namespace Nz switch (m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: NazaraInternalError("Invalid protocol Any at this point"); return SocketState_NotConnected; @@ -48,6 +49,8 @@ namespace Nz bool UdpSocket::Create(NetProtocol protocol) { + NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); + return Open(protocol); } diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index a8e462d5d..d39f9adb1 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4195,9 +4195,9 @@ namespace Nz if (!m_sharedString.unique()) { - auto newSharedString = std::make_shared(GetSize()); + auto newSharedString = std::make_shared(GetSize(), GetCapacity()); if (!discardContent) - std::memcpy(newSharedString->string.get(), GetConstBuffer(), GetSize()); + std::memcpy(newSharedString->string.get(), GetConstBuffer(), GetSize()+1); m_sharedString = std::move(newSharedString); } diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 820ed557a..b746756d9 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -217,6 +217,8 @@ namespace Nz for (auto& pair : m_renderInfos) { RenderIndices& indices = pair.second; + if (indices.count == 0) + continue; //< Ignore empty render indices SparsePtr color = colorPtr + indices.first*4; SparsePtr pos = posPtr + indices.first*4; diff --git a/src/Nazara/Network/IpAddress.cpp b/src/Nazara/Network/IpAddress.cpp index 473ce579f..b44412aca 100644 --- a/src/Nazara/Network/IpAddress.cpp +++ b/src/Nazara/Network/IpAddress.cpp @@ -57,6 +57,7 @@ namespace Nz switch (m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: break; case NetProtocol_IPv4: @@ -80,6 +81,7 @@ namespace Nz switch (m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: break; case NetProtocol_IPv4: @@ -151,6 +153,8 @@ namespace Nz String IpAddress::ResolveAddress(const IpAddress& address, String* service, ResolveError* error) { + NazaraAssert(address.IsValid(), "Invalid address"); + String hostname; IpAddressImpl::ResolveAddress(address, &hostname, service, error); @@ -159,6 +163,8 @@ namespace Nz std::vector IpAddress::ResolveHostname(NetProtocol protocol, const String& hostname, const String& service, ResolveError* error) { + NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); + return IpAddressImpl::ResolveHostname(protocol, hostname, service, error); } diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 41c48ac1c..4c13c5c03 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -57,10 +57,12 @@ namespace Nz IpAddress hostnameAddress; for (const HostnameInfo& result : results) { - //TODO: Check PF_ type (TCP) if (!result.address) continue; + if (result.socketType != SocketType_TCP) + continue; + hostnameAddress = result.address; break; //< Take first valid address } diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 1a5de9ada..b23ceae04 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -21,12 +21,12 @@ namespace Nz return GetAddrInfoW(hostname.GetWideString().c_str(), service.GetWideString().c_str(), &hints, &servinfo); } - int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service) + int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service, INT flags) { std::array hostnameBuffer; std::array serviceBuffer; - int result = GetNameInfoW(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), NI_NUMERICSERV); + int result = GetNameInfoW(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags); if (result == 0) { if (hostname) @@ -51,12 +51,12 @@ namespace Nz return getaddrinfo(hostname.GetConstBuffer(), service.GetConstBuffer(), hints, results); } - int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service) + int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service, INT flags) { std::array hostnameBuffer; std::array serviceBuffer; - int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), NI_NUMERICSERV); + int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags); if (result == 0) { if (hostname) @@ -153,7 +153,7 @@ namespace Nz SockAddrBuffer socketAddress; socklen_t socketAddressLen = ToSockAddr(ipAddress, socketAddress.data()); - if (Detail::GetHostnameInfo(reinterpret_cast(socketAddress.data()), socketAddressLen, hostname, service) != 0) + if (Detail::GetHostnameInfo(reinterpret_cast(socketAddress.data()), socketAddressLen, hostname, service, NI_NUMERICSERV) != 0) { if (error) *error = TranslateWSAErrorToResolveError(WSAGetLastError()); @@ -174,6 +174,7 @@ namespace Nz Detail::addrinfoImpl hints; std::memset(&hints, 0, sizeof(Detail::addrinfoImpl)); hints.ai_family = SocketImpl::TranslateNetProtocolToAF(procol); + hints.ai_flags = AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; Detail::addrinfoImpl* servinfo; @@ -196,9 +197,8 @@ namespace Nz HostnameInfo result; result.address = FromAddrinfo(p); result.canonicalName = String::Unicode(p->ai_canonname); - result.family = p->ai_family; - result.flags = p->ai_flags; - result.socketType = p->ai_socktype; + result.protocol = TranslatePFToNetProtocol(p->ai_family); + result.socketType = TranslateSockToNetProtocol(p->ai_socktype); results.push_back(result); } @@ -252,6 +252,39 @@ namespace Nz return 0; } + NetProtocol IpAddressImpl::TranslatePFToNetProtocol(int family) + { + switch (family) + { + case PF_INET: + return NetProtocol_IPv4; + + case PF_INET6: + return NetProtocol_IPv6; + + default: + return NetProtocol_Unknown; + } + } + + SocketType IpAddressImpl::TranslateSockToNetProtocol(int socketType) + { + switch (socketType) + { + case SOCK_STREAM: + return SocketType_TCP; + + case SOCK_DGRAM: + return SocketType_UDP; + + case SOCK_RAW: + return SocketType_Raw; + + default: + return SocketType_Unknown; + } + } + ResolveError IpAddressImpl::TranslateWSAErrorToResolveError(int error) { switch (error) diff --git a/src/Nazara/Network/Win32/IpAddressImpl.hpp b/src/Nazara/Network/Win32/IpAddressImpl.hpp index ad3ca6689..4b27bef32 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.hpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.hpp @@ -26,6 +26,8 @@ namespace Nz static std::vector ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error); static socklen_t ToSockAddr(const IpAddress& ipAddress, void* buffer); + static NetProtocol TranslatePFToNetProtocol(int family); + static SocketType TranslateSockToNetProtocol(int socketType); static ResolveError TranslateWSAErrorToResolveError(int error); }; } diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 7fd34405a..7d83ce99d 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -703,7 +703,8 @@ namespace Nz static int addressFamily[] = { AF_UNSPEC, //< NetProtocol_Any AF_INET, //< NetProtocol_IPv4 - AF_INET6 //< NetProtocol_IPv6 + AF_INET6, //< NetProtocol_IPv6 + -1 //< NetProtocol_Unknown }; static_assert(sizeof(addressFamily) / sizeof(int) == NetProtocol_Max + 1, "Address family array is incomplete"); @@ -715,9 +716,10 @@ namespace Nz NazaraAssert(type <= SocketType_Max, "Socket type has value out of enum"); static int socketType[] = { - SOCK_RAW, //< SocketType_Raw - SOCK_STREAM, //< SocketType_TCP - SOCK_DGRAM //< SocketType_UDP + SOCK_RAW, //< SocketType_Raw + SOCK_STREAM, //< SocketType_TCP + SOCK_DGRAM, //< SocketType_UDP + -1 //< SocketType_Unknown }; static_assert(sizeof(socketType) / sizeof(int) == SocketType_Max + 1, "Socket type array is incomplete");