#pragma once
#include <iostream>
#include <string>
#include <cstdint>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <memory>

class BufferedReader {
 public:
    explicit BufferedReader(PackageStream* stream);
    int32_t Read(char* output_buffer, int32_t buffer_len);
    PackageStream* ps;
    char buf[1500];
    std::string str = "";
    int32_t pos = 0;
};

BufferedReader::BufferedReader(PackageStream* stream) {
    int len = 0, add = -1;
    while (add != 0) {
        add = stream->ReadPackage(buf + len);
        len += add;
    }
    for (int i = 0; i < len; i++) {
        str += buf[i];
    }
}

int32_t BufferedReader::Read(char* output_buffer, int32_t buffer_len) {
    int sum = 0, add = -1;
    for (int i = 0; i < buffer_len && add != 0; i++) {
        int32_t next_pos = std::min<int32_t>(str.size(),  pos + 1);
        int32_t len = next_pos - pos;

        memcpy(output_buffer + sum, str.c_str() + pos, len);
        pos = next_pos;

        add = len;
        sum += add;
    }
    return sum;
}