mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-22 21:09:52 +00:00
Use CharQueue in Buffer
This commit is contained in:
parent
cb27df02f3
commit
d1d7ddf310
@ -9,9 +9,7 @@
|
||||
|
||||
char *Buffer::Append(size_t length) {
|
||||
if (length > 0) {
|
||||
size_t old_size = data_.size();
|
||||
data_.resize(old_size + length);
|
||||
return &data_[0] + old_size;
|
||||
return data_.push_back_write(length);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
@ -33,8 +31,11 @@ void Buffer::Append(const char *str) {
|
||||
void Buffer::Append(const Buffer &other) {
|
||||
size_t len = other.size();
|
||||
if (len > 0) {
|
||||
char *dest = Append(len);
|
||||
memcpy(dest, &other.data_[0], len);
|
||||
// Append other to the current buffer.
|
||||
other.data_.iterate_blocks([&](const char *data, size_t size) {
|
||||
data_.push_back(data, size);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,8 +58,8 @@ void Buffer::Take(size_t length, std::string *dest) {
|
||||
}
|
||||
|
||||
void Buffer::Take(size_t length, char *dest) {
|
||||
memcpy(dest, &data_[0], length);
|
||||
data_.erase(data_.begin(), data_.begin() + length);
|
||||
size_t retval = data_.pop_front_bulk(dest, length);
|
||||
_dbg_assert_(retval == length);
|
||||
}
|
||||
|
||||
int Buffer::TakeLineCRLF(std::string *dest) {
|
||||
@ -79,7 +80,7 @@ void Buffer::Skip(size_t length) {
|
||||
ERROR_LOG(Log::IO, "Truncating length in Buffer::Skip()");
|
||||
length = data_.size();
|
||||
}
|
||||
data_.erase(data_.begin(), data_.begin() + length);
|
||||
data_.skip(length);
|
||||
}
|
||||
|
||||
int Buffer::SkipLineCRLF() {
|
||||
@ -92,9 +93,10 @@ int Buffer::SkipLineCRLF() {
|
||||
}
|
||||
}
|
||||
|
||||
// This relies on having buffered data!
|
||||
int Buffer::OffsetToAfterNextCRLF() {
|
||||
for (int i = 0; i < (int)data_.size() - 1; i++) {
|
||||
if (data_[i] == '\r' && data_[i + 1] == '\n') {
|
||||
if (data_.peek(i) == '\r' && data_.peek(i + 1) == '\n') {
|
||||
return i + 2;
|
||||
}
|
||||
}
|
||||
@ -124,7 +126,11 @@ bool Buffer::FlushToFile(const Path &filename) {
|
||||
if (!f)
|
||||
return false;
|
||||
if (!data_.empty()) {
|
||||
fwrite(&data_[0], 1, data_.size(), f);
|
||||
// Write the buffer to the file.
|
||||
data_.iterate_blocks([=](const char *blockData, size_t blockSize) {
|
||||
return fwrite(blockData, 1, blockSize, f) == blockSize;
|
||||
});
|
||||
data_.clear();
|
||||
}
|
||||
fclose(f);
|
||||
return true;
|
||||
@ -132,5 +138,8 @@ bool Buffer::FlushToFile(const Path &filename) {
|
||||
|
||||
void Buffer::PeekAll(std::string *dest) {
|
||||
dest->resize(data_.size());
|
||||
memcpy(&(*dest)[0], &data_[0], data_.size());
|
||||
data_.iterate_blocks(([=](const char *blockData, size_t blockSize) {
|
||||
dest->append(blockData, blockSize);
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "Common/Common.h"
|
||||
#include "Common/Data/Collections/CharQueue.h"
|
||||
|
||||
class Path;
|
||||
|
||||
@ -72,12 +73,12 @@ public:
|
||||
// Utilities. Try to avoid checking for size.
|
||||
size_t size() const { return data_.size(); }
|
||||
bool empty() const { return size() == 0; }
|
||||
void clear() { data_.resize(0); }
|
||||
void clear() { data_.clear(); }
|
||||
bool IsVoid() const { return void_; }
|
||||
|
||||
protected:
|
||||
// TODO: Find a better internal representation, like a cord.
|
||||
std::vector<char> data_;
|
||||
// Custom queue implementation.
|
||||
CharQueue data_;
|
||||
bool void_ = false;
|
||||
|
||||
private:
|
||||
|
@ -36,27 +36,32 @@ void RequestProgress::Update(int64_t downloaded, int64_t totalBytes, bool done)
|
||||
|
||||
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 endTimeout = time_now_d() + timeout;
|
||||
while (!ready) {
|
||||
if (cancelled && *cancelled)
|
||||
return false;
|
||||
ready = fd_util::WaitUntilReady(sock, CANCEL_INTERVAL, true);
|
||||
if (!ready && time_now_d() > endTimeout) {
|
||||
ERROR_LOG(Log::IO, "FlushSocket timed out");
|
||||
|
||||
data_.iterate_blocks([&](const char *data, size_t size) {
|
||||
for (size_t pos = 0, end = size; pos < end; ) {
|
||||
bool ready = false;
|
||||
double endTimeout = time_now_d() + timeout;
|
||||
while (!ready) {
|
||||
if (cancelled && *cancelled)
|
||||
return false;
|
||||
ready = fd_util::WaitUntilReady(sock, CANCEL_INTERVAL, true);
|
||||
if (!ready && time_now_d() > endTimeout) {
|
||||
ERROR_LOG(Log::IO, "FlushSocket timed out");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int sent = send(sock, &data[pos], end - pos, MSG_NOSIGNAL);
|
||||
// TODO: Do we need some retry logic here, instead of just giving up?
|
||||
if (sent < 0) {
|
||||
ERROR_LOG(Log::IO, "FlushSocket failed to send: %d", errno);
|
||||
return false;
|
||||
}
|
||||
pos += sent;
|
||||
}
|
||||
int sent = send(sock, &data_[pos], end - pos, MSG_NOSIGNAL);
|
||||
// TODO: Do we need some retry logic here, instead of just giving up?
|
||||
if (sent < 0) {
|
||||
ERROR_LOG(Log::IO, "FlushSocket failed to send: %d", errno);
|
||||
return false;
|
||||
}
|
||||
pos += sent;
|
||||
}
|
||||
data_.resize(0);
|
||||
return true;
|
||||
});
|
||||
|
||||
data_.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user