#include #include 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(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; };