#pragma once #include #include #include #include #include class BufferedReader { public: explicit BufferedReader(PackageStream *stream) : stream(stream), buffer(new char[stream->PackageLen()]) { } int32_t Read(char *output_buffer, int32_t buffer_len) { int32_t buffer_size = static_cast(strlen(buffer.get())); int32_t real_size = std::min(buffer_size, buffer_len); memcpy(output_buffer, buffer.get(), real_size); memcpy(buffer.get(), buffer.get() + real_size, buffer_size - real_size); AddZero(buffer.get(), buffer_size - real_size); unique_ptr tmp_buf(new char[stream->PackageLen()]); for (int32_t last_result = INT32_MAX; real_size < buffer_len && last_result != 0;) { last_result = stream->ReadPackage(tmp_buf.get()); int32_t add_size; if (real_size + last_result > buffer_len) { add_size = buffer_len - real_size; memcpy(output_buffer + real_size, tmp_buf.get(), add_size); memcpy(buffer.get(), tmp_buf.get() + add_size, real_size + last_result - buffer_len); AddZero(buffer.get(), real_size + last_result - buffer_len); } else { add_size = last_result; memcpy(output_buffer + real_size, tmp_buf.get(), add_size); } real_size += add_size; } return real_size; } private: void AddZero(char* c, int32_t index) { c[index] = 0; } PackageStream *stream; unique_ptr buffer; }; // int32_t Read(char *output_buffer, int32_t buffer_len) { // int32_t real_size = std::min // (buffer_len, static_cast(strlen(this->buffer))); // int32_t last_return = 1; // memcpy(output_buffer, this->buffer, real_size); // char* tmp_buf = new char[this->stream->PackageLen() + 1]; // memcpy(tmp_buf, this->buffer, strlen(this->buffer)); // memcpy(this->buffer, tmp_buf + real_size, strlen(tmp_buf)); // memset(tmp_buf, 0, strlen(tmp_buf)); // // while (real_size < buffer_len && last_return != 0) { // last_return = stream->ReadPackage(tmp_buf); // int add_size = real_size + last_return > buffer_len ? // buffer_len - real_size : last_return; // memcpy(output_buffer + real_size, tmp_buf, add_size); // real_size += add_size; // memset(this->buffer, 0, strlen(this->buffer)); // memcpy(this->buffer, tmp_buf + add_size, strlen(tmp_buf)); // memset(tmp_buf, 0, strlen(tmp_buf)); // } // // delete[] tmp_buf; // return real_size; // }