#include <cstring>
#include <memory>
#include <string>
#include <cstdint>
class BufferedReader {
public:
explicit BufferedReader(PackageStream *stream);
int32_t Read(char *output_buffer, int32_t buffer_len);
private:
PackageStream *bufR = nullptr;
std::string _ostBuf{};
};
BufferedReader::BufferedReader(PackageStream *stream)
: bufR(stream) {}
int32_t BufferedReader::Read(char *output_buffer, int32_t buffer_len) {
char *buf = new char[2000];
int32_t readed{};
// ves last buf prochitan
if (_ostBuf.empty()) {
auto ostInBuf = buffer_len - readed;
while (readed < buffer_len) {
auto len = bufR->ReadPackage(buf);
if (len == 0) {
delete[] buf;
return readed;
}
if (
bufR->PackageLen() > ostInBuf) { // ne pomestitsa berem chast'
if (len <= ostInBuf) { // pomestitsa
if (!buf)
return 0;
std::memcpy(output_buffer + readed, buf, len); // look suda
readed += len;
} else { // pomest ne vse ostatok v _ostatok
if (!buf)
return 0; // prochitali bolche 4em ost mesta
std::memcpy(output_buffer + readed, buf, ostInBuf);
for (size_t i = 0; i < static_cast<size_t> (len - ostInBuf); ++i)
_ostBuf.push_back(buf[i + readed + ostInBuf]); // ? podumai 3dec oshibka
readed += ostInBuf;
}
} else {
std::memcpy(output_buffer + readed, buf, len);
readed += len;
ostInBuf -= readed;
}
}
delete[] buf;
return readed;
} else { // осталось с прошлого большого чтения
if (auto len = _ostBuf.size(); len <= static_cast<size_t> (buffer_len)) {
std::memcpy(output_buffer, _ostBuf.c_str(), len);
_ostBuf = std::string();
readed += len;
if (len == buffer_len) {
delete[] buf;
return len;
} else {
delete[] buf;
return readed + Read(output_buffer + len, buffer_len - len);
}
} else { //fuck
std::memcpy(output_buffer, _ostBuf.c_str(), buffer_len);
std::string new_ost{};
readed += buffer_len;
for (size_t i = 0; i < _ostBuf.size() - buffer_len; ++i)
new_ost.push_back(_ostBuf[buffer_len + i]);
_ostBuf = new_ost;
delete[] buf;
return buffer_len;
}
}
}