#pragma once

class BufferedReader {
public:
    explicit BufferedReader(PackageStream *stream): stream(stream) {};

    int32_t Read(char *output_buffer, int32_t buffer_len) {
        while (this->len < buffer_len) {
            int must_got_len = this->stream->PackageLen();
            char *output = new char[must_got_len];
            int got_len = this->stream->ReadPackage(output);
            if (got_len == 0){
                break;
            }
            this->s += output;
            this->len += got_len;
        }
        if (len < buffer_len){
            memcpy(output_buffer, s.c_str(), len);
            s = "";
            int old_len = len;
            len = 0;
            return old_len;
        } else {
            memcpy(output_buffer, s.c_str(), buffer_len);
            s = s.substr(buffer_len);
            len -= buffer_len;
            return buffer_len;
        }
    };
private:
    PackageStream *stream{};
    int len = 0;
    std::string s{};
};