added Socket::sendx() functions
added SocketAddress::set() that accepts a string fixed a bug in nwad-skad.c
This commit is contained in:
@ -26,6 +26,7 @@
|
||||
|
||||
#include <qse/si/Socket.hpp>
|
||||
#include <qse/cmn/str.h>
|
||||
#include "../cmn/mem-prv.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
@ -258,6 +259,151 @@ qse_ssize_t Socket::send (const void* buf, qse_size_t len, const SocketAddress&
|
||||
return n;
|
||||
}
|
||||
|
||||
int Socket::sendx (const void* buf, qse_size_t len, qse_size_t* total_sent) QSE_CPP_NOEXCEPT
|
||||
{
|
||||
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND);
|
||||
|
||||
qse_size_t pos = 0;
|
||||
|
||||
while (pos < len)
|
||||
{
|
||||
qse_ssize_t n = ::send(this->handle, (char*)buf + pos, len - pos, 0);
|
||||
if (n <= -1)
|
||||
{
|
||||
this->setErrorCode (syserr_to_errnum(errno));
|
||||
if (total_sent) *total_sent = pos;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos += n;
|
||||
}
|
||||
|
||||
if (total_sent) *total_sent = pos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Socket::sendx (const void* buf, qse_size_t len, const SocketAddress& dstaddr, qse_size_t* total_sent) QSE_CPP_NOEXCEPT
|
||||
{
|
||||
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND);
|
||||
|
||||
qse_size_t pos = 0;
|
||||
|
||||
while (pos < len)
|
||||
{
|
||||
qse_ssize_t n = ::sendto(this->handle, (char*)buf + pos, len - pos, 0, (struct sockaddr*)dstaddr.getAddrPtr(), dstaddr.getAddrSize());
|
||||
if (n == -1)
|
||||
{
|
||||
this->setErrorCode (syserr_to_errnum(errno));
|
||||
if (total_sent) *total_sent = pos;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos += n;
|
||||
}
|
||||
|
||||
if (total_sent) *total_sent = pos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Socket::sendx (qse_ioptl_t* iov, int count, qse_size_t* total_sent) QSE_CPP_NOEXCEPT
|
||||
{
|
||||
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND);
|
||||
|
||||
#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
|
||||
int index = 0;
|
||||
qse_size_t total = 0;
|
||||
int backup_index = -1;
|
||||
qse_ioptl_t backup;
|
||||
|
||||
#if defined(HAVE_SENDMSG)
|
||||
struct msghdr msg;
|
||||
QSE_MEMSET (&msg, 0, QSE_SIZEOF(msg));
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
ssize_t nwritten;
|
||||
|
||||
#if defined(HAVE_SENDMSG)
|
||||
msg.msg_iov = (struct iovec*)&iov[index];
|
||||
msg.msg_iovlen = count - index;
|
||||
nwritten = ::sendmsg(this->handle, &msg, 0);
|
||||
#else
|
||||
nwritten = ::writev(this->handle, (const struct iovec*)&iov[index], count - index);
|
||||
#endif
|
||||
if (nwritten <= -1)
|
||||
{
|
||||
this->setErrorCode (syserr_to_errnum(errno));
|
||||
if (backup_index >= 0) iov[backup_index] = backup;
|
||||
if (total_sent) *total_sent = total;
|
||||
return -1;
|
||||
}
|
||||
|
||||
total += nwritten;
|
||||
|
||||
while (index < count && (qse_size_t)nwritten >= iov[index].len)
|
||||
nwritten -= iov[index++].len;
|
||||
|
||||
if (index == count) break;
|
||||
|
||||
if (backup_index != index)
|
||||
{
|
||||
if (backup_index >= 0) iov[backup_index] = backup;
|
||||
backup = iov[index];
|
||||
backup_index = index;
|
||||
}
|
||||
|
||||
iov[index].ptr = (void*)((qse_uint8_t*)iov[index].ptr + nwritten);
|
||||
iov[index].len -= nwritten;
|
||||
}
|
||||
|
||||
if (backup_index >= 0) iov[backup_index] = backup;
|
||||
if (total_sent) *total_sent = total;
|
||||
return 0;
|
||||
|
||||
#else
|
||||
qse_ioptl_t* v, * ve;
|
||||
qse_size_t total = 0, pos, rem;
|
||||
ssize_t nwritten;
|
||||
|
||||
v = iov;
|
||||
ve = v + count;
|
||||
|
||||
while (v < ve)
|
||||
{
|
||||
if (v->len <= 0)
|
||||
{
|
||||
v++;
|
||||
continue;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
rem = v->len;
|
||||
write_again:
|
||||
nwritten = ::send(this->handle, (qse_uint8_t*)v->ptr + pos, rem, 0);
|
||||
if (nwritten <= -1)
|
||||
{
|
||||
this->setErrorCode (syserr_to_errnum(errno));
|
||||
if (total_sent) *total_sent = total;
|
||||
return -1;
|
||||
}
|
||||
|
||||
total += nwritten;
|
||||
if ((qse_size_t)nwritten < rem)
|
||||
{
|
||||
pos += nwritten;
|
||||
rem -= nwritten;
|
||||
goto write_again;
|
||||
}
|
||||
|
||||
v++;
|
||||
}
|
||||
|
||||
if (total_sent) *total_sent = total;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
qse_ssize_t Socket::receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT
|
||||
{
|
||||
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND);
|
||||
|
@ -195,10 +195,24 @@ int SocketAddress::set (const qse_skad_t* skad)
|
||||
|
||||
int SocketAddress::set (const qse_nwad_t* nwad)
|
||||
{
|
||||
return qse_nwadtoskad (nwad, &this->skad);
|
||||
return qse_nwadtoskad(nwad, &this->skad);
|
||||
}
|
||||
|
||||
|
||||
int SocketAddress::set (const qse_mchar_t* str)
|
||||
{
|
||||
qse_nwad_t nwad;
|
||||
if (qse_mbstonwad(str, &nwad) <= -1) return -1;
|
||||
return qse_nwadtoskad(&nwad, &this->skad);
|
||||
}
|
||||
|
||||
int SocketAddress::set (const qse_wchar_t* str)
|
||||
{
|
||||
qse_nwad_t nwad;
|
||||
if (qse_wcstonwad(str, &nwad) <= -1) return -1;
|
||||
return qse_nwadtoskad(&nwad, &this->skad);
|
||||
}
|
||||
|
||||
/////////////////////////////////
|
||||
QSE_END_NAMESPACE(QSE)
|
||||
/////////////////////////////////
|
||||
|
@ -270,29 +270,29 @@ int qse_skadsize (const qse_skad_t* skad)
|
||||
{
|
||||
switch (FAMILY(skad))
|
||||
{
|
||||
#if defined(AF_INET)
|
||||
#if defined(AF_INET)
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in in;
|
||||
return QSE_SIZEOF(in);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(AF_INET6)
|
||||
#if defined(AF_INET6)
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in in6;
|
||||
struct sockaddr_in6 in6;
|
||||
return QSE_SIZEOF(in6);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(AF_UNIX)
|
||||
#if defined(AF_UNIX)
|
||||
case AF_UNIX:
|
||||
{
|
||||
struct sockaddr_un un;
|
||||
return QSE_SIZEOF(un);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user