#pragma once

#include <string>

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{};
};