#include <algorithm>
 
class BufferedReader {
 private:
    PackageStream* source = nullptr;
    int32_t offset = 0;
    int32_t shift = 0;
    char* myBuf;
 public:
    explicit BufferedReader(PackageStream* stream);
    int32_t Read(char* output_buffer, int32_t buffer_len);
    ~BufferedReader();
};
 
BufferedReader::BufferedReader(PackageStream *stream) {
    source = stream;
    myBuf = new char(stream->PackageLen());
}
 
BufferedReader::~BufferedReader() {
    delete[] myBuf;
}
 
int32_t BufferedReader::Read(char *output_buffer, int32_t buffer_len) {
    int32_t realSize = 0;
    for (int32_t i = 0; i < buffer_len; ++i) {
        if (offset == shift) {
            offset = source->ReadPackage(myBuf);
            if (offset == 0) return realSize;
            shift = 0;
        }
        output_buffer[i] = myBuf[shift];
        realSize++;
        shift++;
    }
    return realSize;
}