138 lines
2.4 KiB
C++
138 lines
2.4 KiB
C++
|
|
// PHZ
|
||
|
|
// 2018-5-15
|
||
|
|
|
||
|
|
#include "BufferWriter.h"
|
||
|
|
#include "Socket.h"
|
||
|
|
#include "SocketUtil.h"
|
||
|
|
|
||
|
|
using namespace xop;
|
||
|
|
|
||
|
|
void xop::WriteUint32BE(char* p, uint32_t value)
|
||
|
|
{
|
||
|
|
p[0] = value >> 24;
|
||
|
|
p[1] = value >> 16;
|
||
|
|
p[2] = value >> 8;
|
||
|
|
p[3] = value & 0xff;
|
||
|
|
}
|
||
|
|
|
||
|
|
void xop::WriteUint32LE(char* p, uint32_t value)
|
||
|
|
{
|
||
|
|
p[0] = value & 0xff;
|
||
|
|
p[1] = value >> 8;
|
||
|
|
p[2] = value >> 16;
|
||
|
|
p[3] = value >> 24;
|
||
|
|
}
|
||
|
|
|
||
|
|
void xop::WriteUint24BE(char* p, uint32_t value)
|
||
|
|
{
|
||
|
|
p[0] = value >> 16;
|
||
|
|
p[1] = value >> 8;
|
||
|
|
p[2] = value & 0xff;
|
||
|
|
}
|
||
|
|
|
||
|
|
void xop::WriteUint24LE(char* p, uint32_t value)
|
||
|
|
{
|
||
|
|
p[0] = value & 0xff;
|
||
|
|
p[1] = value >> 8;
|
||
|
|
p[2] = value >> 16;
|
||
|
|
}
|
||
|
|
|
||
|
|
void xop::WriteUint16BE(char* p, uint16_t value)
|
||
|
|
{
|
||
|
|
p[0] = value >> 8;
|
||
|
|
p[1] = value & 0xff;
|
||
|
|
}
|
||
|
|
|
||
|
|
void xop::WriteUint16LE(char* p, uint16_t value)
|
||
|
|
{
|
||
|
|
p[0] = value & 0xff;
|
||
|
|
p[1] = value >> 8;
|
||
|
|
}
|
||
|
|
|
||
|
|
BufferWriter::BufferWriter(int capacity)
|
||
|
|
: max_queue_length_(capacity)
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
bool BufferWriter::Append(std::shared_ptr<char> data, uint32_t size, uint32_t index)
|
||
|
|
{
|
||
|
|
if (size <= index) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((int)buffer_.size() >= max_queue_length_) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
Packet pkt = { data, size, index };
|
||
|
|
buffer_.emplace(std::move(pkt));
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool BufferWriter::Append(const char* data, uint32_t size, uint32_t index)
|
||
|
|
{
|
||
|
|
if (size <= index) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((int)buffer_.size() >= max_queue_length_) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
Packet pkt;
|
||
|
|
pkt.data.reset(new char[size+512]);
|
||
|
|
memcpy(pkt.data.get(), data, size);
|
||
|
|
pkt.size = size;
|
||
|
|
pkt.writeIndex = index;
|
||
|
|
buffer_.emplace(std::move(pkt));
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
int BufferWriter::Send(SOCKET sockfd, int timeout)
|
||
|
|
{
|
||
|
|
if (timeout > 0) {
|
||
|
|
SocketUtil::SetBlock(sockfd, timeout);
|
||
|
|
}
|
||
|
|
|
||
|
|
int ret = 0;
|
||
|
|
int count = 1;
|
||
|
|
|
||
|
|
do
|
||
|
|
{
|
||
|
|
if (buffer_.empty()) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
count -= 1;
|
||
|
|
Packet &pkt = buffer_.front();
|
||
|
|
ret = ::send(sockfd, pkt.data.get() + pkt.writeIndex, pkt.size - pkt.writeIndex, 0);
|
||
|
|
if (ret > 0) {
|
||
|
|
pkt.writeIndex += ret;
|
||
|
|
if (pkt.size == pkt.writeIndex) {
|
||
|
|
count += 1;
|
||
|
|
buffer_.pop();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (ret < 0) {
|
||
|
|
#if defined(__linux) || defined(__linux__)
|
||
|
|
if (errno == EINTR || errno == EAGAIN)
|
||
|
|
#elif defined(WIN32) || defined(_WIN32)
|
||
|
|
int error = WSAGetLastError();
|
||
|
|
if (error == WSAEWOULDBLOCK || error == WSAEINPROGRESS || error == 0)
|
||
|
|
#endif
|
||
|
|
{
|
||
|
|
ret = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} while (count > 0);
|
||
|
|
|
||
|
|
if (timeout > 0) {
|
||
|
|
SocketUtil::SetNonBlock(sockfd);
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
|