/* Copyright (c) 2018, 2024, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is designed to work with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have either included with the program or referenced in the documentation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef BASIC_ISTREAM_INCLUDED #define BASIC_ISTREAM_INCLUDED #include "my_inttypes.h" #include "my_io.h" #include "my_sys.h" /** The abstract class for basic byte input streams which provides read operations. */ class Basic_istream { public: /** Read some bytes from the input stream. It should read exact 'length' bytes unless error happens or it reaches the end of the stream. It should block when reaching the end of a pipe that is not closed. @param[out] buffer Where data will be put in. @param[in] length The number of bytes that you want to read. length should not be larger than max long. @return Return values fall into three cases: @retval 'length' Read 'length' bytes successfully @retval >=0 Reach EOF, return the number of bytes actually read. It is between 0 and length-1. @retval -1 Error. */ virtual ssize_t read(unsigned char *buffer, size_t length) = 0; virtual ~Basic_istream() = default; }; /** The abstract class for seekable input streams which have fixed length and provide seek operation. */ class Basic_seekable_istream : public Basic_istream { public: /** Puts the read position to a given offset. The offset counts from the beginning of the stream. In case an implementing class transforms the data in a way that does not preserve positions, the offset here will be relative to the bytes that are read out from the stream, not relative to the bytes in lower layer storage. it is allowed for a subclass to return success even if the position is greater than the size of the file. Error may be returned by the next read for this case. Users should call length() if they need to check that the position is within bounds. @param[in] offset Where the read position will be. @retval false Success @retval true Error */ virtual bool seek(my_off_t offset) = 0; /** The total length of the stream. */ virtual my_off_t length() = 0; ~Basic_seekable_istream() override = default; }; /** A file input stream based on IO_CACHE class. It can be used to open a file and provide a Basic_seekable_istream based on the file. */ class IO_CACHE_istream : public Basic_seekable_istream { public: IO_CACHE_istream(); IO_CACHE_istream(const IO_CACHE_istream &) = delete; IO_CACHE_istream &operator=(const IO_CACHE_istream &) = delete; ~IO_CACHE_istream() override; /** Open the stream. It opens related file and initializes IO_CACHE. @param[in] log_file_key The PSI_file_key for this stream @param[in] log_cache_key The PSI_file_key for the IO_CACHE @param[in] file_name The file to be opened @param[in] flags The flags used by IO_CACHE. @param[in] cache_size Cache size of the IO_CACHE. @retval false Success @retval true Error */ bool open( #ifdef HAVE_PSI_INTERFACE PSI_file_key log_file_key, PSI_file_key log_cache_key, #endif const char *file_name, myf flags, size_t cache_size = IO_SIZE * 2); /** Closes the stream. It deinitializes IO_CACHE and closes the file it opened. */ void close(); ssize_t read(unsigned char *buffer, size_t length) override; bool seek(my_off_t bytes) override; /** Get the length of the file. */ my_off_t length() override; private: IO_CACHE m_io_cache; }; /** A stdin input stream based on IO_CACHE. It provides a Basic_istream based on stdin. */ class Stdin_istream : public Basic_istream { public: Stdin_istream(); Stdin_istream(const Stdin_istream &) = delete; Stdin_istream &operator=(const Stdin_istream &) = delete; ~Stdin_istream() override; /** Opens the stdin stream. It initializes the IO_CACHE with stdin. @param[out] errmsg An error message is returned if any error happens. */ bool open(std::string *errmsg); /** Closes the stream. It deinitializes IO_CACHE. */ void close(); ssize_t read(unsigned char *buffer, size_t length) override; /** Skip bytes data from the stdin stream. @param[in] bytes How many bytes should be skipped */ bool skip(my_off_t bytes); private: IO_CACHE m_io_cache; }; #endif // BASIC_ISTREAM_INCLUDED