#pragma once
#include <iostream>
#include <utility>
#include <algorithm>
#include <string>
#include <cmath>
#include <memory>
class BufferedReader {
public:
explicit BufferedReader(PackageStream *stream) {
this->stream = stream;
buffer = new char[stream->PackageLen() + 1];
}
int32_t Read(char *output_buffer, int32_t buffer_len) {
int32_t buffer_size = static_cast<int32_t>(strlen(buffer));
int32_t real_size = std::min<int32_t>(buffer_size, buffer_len);
memcpy(output_buffer, buffer, real_size);
memcpy(buffer, buffer + real_size,
buffer_size - real_size);
AddZero(buffer + buffer_size - real_size);
char* tmp_buf = new char[stream->PackageLen() + 1];
for (int32_t last_result = INT32_MAX;
real_size < buffer_len && last_result != 0;) {
last_result = stream->ReadPackage(tmp_buf);
int32_t add_size;
if (real_size + last_result > buffer_len) {
add_size = buffer_len - real_size;
memcpy(output_buffer + real_size, tmp_buf, add_size);
memcpy(buffer, tmp_buf + add_size,
real_size + last_result - buffer_len);
AddZero(buffer + real_size + last_result - buffer_len);
} else {
add_size = last_result;
memcpy(output_buffer + real_size, tmp_buf, add_size);
}
real_size += add_size;
}
delete[] tmp_buf;
return real_size;
}
~BufferedReader() {
delete[] buffer;
}
private:
void AddZero(char* c) const {
*c = 0;
}
PackageStream *stream;
char* buffer;
};