fedor-resh

Untitled

Dec 16th, 2023 (edited)
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.80 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <memory>
  4. #include <algorithm>
  5. /*
  6.  * Напишите класс StdInputStream, который является оберткой над классом std::istream и позволяет читать заданное
  7.  * количество байт из входного потока по данному указателю с помощью метода Read. Метод Read выглядит следующим образом:
  8.  * `std::streamsize Read(char* buffer, std::streamsize numBytes)`, тут
  9.  * - buffer -- указатель, по адресу которого будут записаны прочитанные из потока байты
  10.  * - numBytes -- максимальное количество байтов, которое мы хотим прочитать
  11.  * - возвращаемое значение -- сколько байтов было прочитано на самом деле.
  12.  *
  13.  * Также необходимо написать класс BufferedStdInputStream, который реализует такой же интерфейс, буферизует прочитанные
  14.  * из потока данные. Если при вызове метода Read в буфере еще остались непрочитанные данные от предыдущего вызова,
  15.  * то нужно сначала использовать их, а только потом читать из входного потока, если данных в буфере не хватило.
  16.  *
  17.  * Для того чтобы абстрагировать вызывающий код от нюансов реализации этих классов, предусмотрите класс StdInputStreamBuilder,
  18.  * с помощью которого можно получить объект типа StdInputStream или BufferedStdInputStream в зависимости от того,
  19.  * нужна буферизация или нет (см функцию main)
  20.  */
  21.  
  22. class IInputStream {
  23. public:
  24.     virtual ~IInputStream() = default;
  25.     virtual std::streamsize Read(char* buffer, std::streamsize numBytes) = 0;
  26. };
  27.  
  28. class StdInputStream : public IInputStream {
  29. public:
  30.     StdInputStream(std::istream& stream) : stream_(stream) {}
  31.  
  32.     std::streamsize Read(char* buffer, std::streamsize numBytes) override {
  33.         stream_.read(buffer, numBytes);
  34.         return stream_.gcount();
  35.     }
  36.  
  37. private:
  38.     std::istream& stream_;
  39. };
  40.  
  41. class BufferedStdInputStream : public IInputStream {
  42. public:
  43.     BufferedStdInputStream(std::istream& stream, size_t bufferSize) : stream_(stream), bufferSize_(bufferSize) {
  44.         buffer_ = new char[bufferSize_];
  45.         FillBuffer();
  46.     }
  47.  
  48.     std::streamsize Read(char* buffer, std::streamsize numBytes) override {
  49.         std::streamsize readBytes = 0;
  50.         while (readBytes < numBytes) {
  51.             if (bufferPos_ == bufferSize_) {
  52.                 FillBuffer();
  53.             }
  54.             buffer[readBytes++] = buffer_[bufferPos_++];
  55.         }
  56.         return readBytes;
  57.     }
  58. private:
  59.     void FillBuffer() {
  60.         stream_.read(buffer_, bufferSize_);
  61.         bufferPos_ = 0;
  62.     }
  63.     std::istream& stream_;
  64.     size_t bufferSize_;
  65.     char* buffer_;
  66.     size_t bufferPos_ = 0;
  67. };
  68.  
  69. class StdInputStreamBuilder {
  70. public:
  71.     StdInputStreamBuilder& Source(std::istream& stdStream) {
  72.         stdStream_ = &stdStream;
  73.         return *this;
  74.     }
  75.  
  76.     StdInputStreamBuilder& Buffered(size_t bufferSize) {
  77.         bufferSize_ = bufferSize;
  78.         return *this;
  79.     }
  80.  
  81.     std::shared_ptr<IInputStream> Build() const {
  82.         if (bufferSize_ > 0) {
  83.             return std::make_shared<BufferedStdInputStream>(*stdStream_, bufferSize_);
  84.         }
  85.         return std::make_shared<StdInputStream>(*stdStream_);
  86.     }
  87.  
  88. private:
  89.     std::istream* stdStream_ = nullptr;
  90.     size_t bufferSize_ = 0;
  91. };
  92.  
  93. int main() {
  94.     std::shared_ptr<IInputStream> unbufferedStream = StdInputStreamBuilder().Source(std::cin).Build();
  95.     std::shared_ptr<IInputStream> bufferedStream = StdInputStreamBuilder().Source(std::cin).Buffered(10).Build();
  96.  
  97.     std::string s(10, '\0');
  98.  
  99.     std::cout << unbufferedStream->Read(s.data(), (std::streamsize)s.size()) << " bytes\n";
  100.     std::cout << s << std::endl;
  101.     std::fill(s.begin(), s.end(), '\0');
  102.  
  103.     std::cout << bufferedStream->Read(s.data(), (std::streamsize)s.size()) << " bytes\n";
  104.     std::cout << s << std::endl;
  105.     std::fill(s.begin(), s.end(), '\0');
  106.  
  107.     std::cout << bufferedStream->Read(s.data(), (std::streamsize)s.size()) << " bytes\n";
  108.     std::cout << s << std::endl;
  109.     std::fill(s.begin(), s.end(), '\0');
  110.  
  111.     std::cout << bufferedStream->Read(s.data(), (std::streamsize)s.size()) << " bytes\n";
  112.     std::cout << s << std::endl;
  113.  
  114.     return 0;
  115. }
  116.  
Advertisement
Add Comment
Please, Sign In to add comment