mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-08-26 07:25:14 +02:00
http: Separate out net buffer code from formatting.
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#undef min
|
||||
#undef max
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
// Default value to 0x00 (do nothing) in systems where it's not supported.
|
||||
#define MSG_NOSIGNAL 0x00
|
||||
#endif
|
||||
|
||||
#include "Common/File/FileDescriptor.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/Net/NetBuffer.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
|
||||
namespace net {
|
||||
|
||||
bool Buffer::FlushSocket(uintptr_t sock, double timeout, bool *cancelled) {
|
||||
static constexpr float CANCEL_INTERVAL = 0.25f;
|
||||
for (size_t pos = 0, end = data_.size(); pos < end; ) {
|
||||
bool ready = false;
|
||||
double leftTimeout = timeout;
|
||||
while (!ready && (leftTimeout >= 0 || cancelled)) {
|
||||
if (cancelled && *cancelled)
|
||||
return false;
|
||||
ready = fd_util::WaitUntilReady(sock, CANCEL_INTERVAL, true);
|
||||
if (!ready && leftTimeout >= 0.0) {
|
||||
leftTimeout -= CANCEL_INTERVAL;
|
||||
if (leftTimeout < 0) {
|
||||
ERROR_LOG(IO, "FlushSocket timed out");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
int sent = send(sock, &data_[pos], (int)(end - pos), MSG_NOSIGNAL);
|
||||
if (sent < 0) {
|
||||
ERROR_LOG(IO, "FlushSocket failed");
|
||||
return false;
|
||||
}
|
||||
pos += sent;
|
||||
|
||||
// Buffer full, don't spin.
|
||||
if (sent == 0 && timeout < 0.0) {
|
||||
sleep_ms(1);
|
||||
}
|
||||
}
|
||||
data_.resize(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Buffer::ReadAll(int fd, int hintSize) {
|
||||
std::vector<char> buf;
|
||||
if (hintSize >= 65536 * 16) {
|
||||
buf.resize(65536);
|
||||
} else if (hintSize >= 1024 * 16) {
|
||||
buf.resize(hintSize / 16);
|
||||
} else {
|
||||
buf.resize(4096);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
int retval = recv(fd, &buf[0], (int)buf.size(), MSG_NOSIGNAL);
|
||||
if (retval == 0) {
|
||||
break;
|
||||
} else if (retval < 0) {
|
||||
ERROR_LOG(IO, "Error reading from buffer: %i", retval);
|
||||
return false;
|
||||
}
|
||||
char *p = Append((size_t)retval);
|
||||
memcpy(p, &buf[0], retval);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Buffer::ReadAllWithProgress(int fd, int knownSize, float *progress, bool *cancelled) {
|
||||
static constexpr float CANCEL_INTERVAL = 0.25f;
|
||||
std::vector<char> buf;
|
||||
if (knownSize >= 65536 * 16) {
|
||||
buf.resize(65536);
|
||||
} else if (knownSize >= 1024 * 16) {
|
||||
buf.resize(knownSize / 16);
|
||||
} else {
|
||||
buf.resize(1024);
|
||||
}
|
||||
|
||||
int total = 0;
|
||||
while (true) {
|
||||
bool ready = false;
|
||||
while (!ready && cancelled) {
|
||||
if (*cancelled)
|
||||
return false;
|
||||
ready = fd_util::WaitUntilReady(fd, CANCEL_INTERVAL, false);
|
||||
}
|
||||
int retval = recv(fd, &buf[0], (int)buf.size(), MSG_NOSIGNAL);
|
||||
if (retval == 0) {
|
||||
return true;
|
||||
} else if (retval < 0) {
|
||||
ERROR_LOG(IO, "Error reading from buffer: %i", retval);
|
||||
return false;
|
||||
}
|
||||
char *p = Append((size_t)retval);
|
||||
memcpy(p, &buf[0], retval);
|
||||
total += retval;
|
||||
if (progress)
|
||||
*progress = (float)total / (float)knownSize;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int Buffer::Read(int fd, size_t sz) {
|
||||
char buf[1024];
|
||||
int retval;
|
||||
size_t received = 0;
|
||||
while ((retval = recv(fd, buf, (int)std::min(sz, sizeof(buf)), MSG_NOSIGNAL)) > 0) {
|
||||
if (retval < 0) {
|
||||
return retval;
|
||||
}
|
||||
char *p = Append((size_t)retval);
|
||||
memcpy(p, buf, retval);
|
||||
sz -= retval;
|
||||
received += retval;
|
||||
if (sz == 0)
|
||||
return 0;
|
||||
}
|
||||
return (int)received;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user