#pragma once
#include <string>
#include <algorithm>
#include <cstring>
class BufferedReader {
public:
explicit BufferedReader(PackageStream* stream) : cur_stream(stream) {}
int32_t Read(char* output_buffer, int32_t buffer_len) {
char* cur_buffer = new char[cur_stream->PackageLen()];
int32_t cur_size = 0, buf_count = 0, cur_len = buffer_len;
if (read_flag) {
while (buffer_len > cur_stream->PackageLen()) {
buf_count = cur_stream->ReadPackage(cur_buffer);
cur_size += buf_count;
buffer = app(buffer, cur_buffer, buf_count);
buffer_len -= cur_stream->PackageLen();
}
buf_count = cur_stream->ReadPackage(cur_buffer);
if (buf_count == 0) {
read_flag = false;
}
cur_size += buf_count;
buffer = app(buffer, cur_buffer, buf_count);
}
if (cur_len < cur_size || cur_len < static_cast<int32_t>
(buffer.size())) {
cpy(output_buffer, buffer.c_str(), cur_len);
buffer.erase(0, cur_len);
delete[] cur_buffer;
return cur_len;
} else {
cur_size = buffer.size();
cpy(output_buffer, buffer.c_str(), buffer.size());
buffer.clear();
delete[] cur_buffer;
return cur_size;
}
}
private:
PackageStream* cur_stream;
std::string buffer = "";
bool read_flag = true;
void cpy(char* old_buf, const char* new_buf, int32_t size) {
for (int32_t i = 0; i < size; ++i) {
old_buf[i] = new_buf[i];
}
}
void app(std::string buf, char* input_str, int32_t size) const {
for (int32_t i = 0; i < size; ++i) {
buf.push_back(input_str[i]);
}
}
};