#include <string>
using std::string;
using std::min;
class PackageStream {
public:
PackageStream(string data, int32_t package_len)
: package_len_(package_len), data_(data) {}
int32_t PackageLen() const {
return package_len_;
}
int32_t ReadPackage(char* buf) {
int32_t next_pos = min<int32_t>(data_.size(), pos_ + PackageLen());
int32_t len = next_pos - pos_;
memcpy(buf, data_.c_str() + pos_, len);
pos_ = next_pos;
return len;
}
private:
const int32_t package_len_;
int32_t pos_ = 0;
string data_;
};
class BufferedReader {
public:
explicit BufferedReader(PackageStream* stream)
: stream(stream) {}
int32_t Read(char* output_buffer, int32_t buffer_len) {
int32_t package_len = stream->PackageLen();
int32_t read_len = 0;
while (buffer_len >= package_len) {
stream->ReadPackage(output_buffer);
buffer_len -= package_len;
read_len += package_len;
}
if (package_len > buffer_len) {
char* temp_buffer = new char[package_len];
stream->ReadPackage(temp_buffer);
memcpy(output_buffer, temp_buffer, buffer_len);
read_len += buffer_len;
}
return read_len;
}
private:
PackageStream* stream;
};