// // aegis - project change supervisor // Copyright (C) 1999, 2002, 2004-2006, 2008, 2009, 2012, 2014 Peter Miller // Copyright (C) 2008, 2009 Walter Franzini // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or (at // your option) any later version. // // 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 for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // #ifndef LIBAEGIS_INPUT_H #define LIBAEGIS_INPUT_H #include #include #include /** * The input abstract class represent a generic input source. */ class input { public: typedef aegis_shared_ptr pointer; /** * The destructor is used to close the given input, and delete all * resources associated with it. Once this returns, the given * input is no longer available for *any* use. (Think of this * method as "close" if it helps.) */ virtual ~input(); // ---------- A ------------------------------------------------------ /** * The at_end method is used to determine whether or not * this input stream is positioned at the end of input. */ bool at_end(void); // ---------- B ------------------------------------------------------ // ---------- C ------------------------------------------------------ // ---------- D ------------------------------------------------------ // ---------- E ------------------------------------------------------ /** * The error method is used to report an error on an input stream. * * @param msg * The error message to be printed. */ void error(const char *msg); // ---------- F ------------------------------------------------------ /** * The fatal_error method is used to report a fatal error on * an input stream. This method does not return. * * @param msg * The error message to be printed. */ void fatal_error(const char *msg) NORETURN; /** * The ftell method is used to determine the current buffered * data position within the input. */ off_t ftell(void); // ---------- G ------------------------------------------------------ /** * The getch method is used to get the next character from * the input. Returns a value<=0 at end-of-file. */ int getch(void) { if (buffer_position < buffer_end) return *buffer_position++; return getc_complicated(); } // ---------- H ------------------------------------------------------ // ---------- I ------------------------------------------------------ /** * The is_remote method is used to determine whether or not an * input stream is from a local file or a remote source. This is * only intended to be a generally informative thing, to provide * information to the user, it isn't (and can't be) utterly * precise. */ virtual bool is_remote(void) const; // ---------- J ------------------------------------------------------ // ---------- K ------------------------------------------------------ /** * The keepalive method is used to set the SO_KEEPALIVE socket * option, if the file is a socket. Does nothing otherwise. */ virtual void keepalive(void); // ---------- L ------------------------------------------------------ /** * The length method is used to determine the length of the input. * May return -1 if the length is unknown. */ virtual off_t length(void) = 0; // ---------- M ------------------------------------------------------ // ---------- N ------------------------------------------------------ /** * The name method is used to determine the name of the input. */ virtual nstring name(void) = 0; // ---------- O ------------------------------------------------------ /** * The one_line method is used to read one line from the input * (up to the next newline character or end of input). * * @param result * Where the text is stored. The newline is not included in the * returned string. * @returns * bool; true if any text was read, false if end-of-file is reached. */ bool one_line(nstring &result); // ---------- P ------------------------------------------------------ /** * The peek method is used to obtain the value of the next input * character, without advancing the read position. * * @returns * the next character, or -1 if the end of file has been reached. */ int peek(void) { int c = getch(); ungetc(c); return c; } /** * The pullback_transfer method is used by input filter classes' * destructors to return unused buffeered input. */ void pullback_transfer(input *to); void pullback_transfer(const input::pointer &to); /** * The pushback_transfer method is used by input filter classes' * destructors to return unused buffered input. */ void pushback_transfer(input *from); void pushback_transfer(const input::pointer &from); // ---------- Q ------------------------------------------------------ // ---------- R ------------------------------------------------------ /** * The read method is used to read buffered data from the given * input stream. At most \a size bytes will be read into * \a buffer. The number of bytes actually read will be returned. * At end-of-file, a value <=0 will be returned, and \a buffer will * be unchanged. All file read errors or format errors are fatal, * and will cause the method to not return. * * @param data * Where to put the results of the read. * @param nbytes * The maximum number of bytes to read. * @returns * The actual number of bytes read, or zero for end-of-file. */ ssize_t read(void *data, size_t nbytes); /** * The read_strictest method is used to read data from the given * input stream. Exactly \a size bytes will be read into * \a buffer. If there are less than \a size bytes available, a * fatal error will result. * * @param data * Where to put the results of the read. * @param size * The number of bytes to read. */ void read_strictest(void *data, size_t size); /** * The read_strict method is used to read data from the given input * stream. Exactly \a size bytes will be read into \a buffer, or * zero bytes at end-of-file. If there are less than \a size bytes * available, a fatal error will result. * * @param data * Where to put the results of the read. * @param size * The number of bytes to read. * @returns * bool; true if data was read, false if end-of-file */ bool read_strict(void *data, size_t size); // ---------- S ------------------------------------------------------ /** * The skip method is used to read data from the given input * stream and discard it. Exactly \a size bytes will be read. If * there are less than \a size bytes available, a fatal error will * result. * * @param size * The number of bytes to discard. */ void skip(size_t size); void swap(input &rhs); // ---------- T ------------------------------------------------------ // ---------- U ------------------------------------------------------ /** * The ungetc method is used to push back a character of input. * Think of it as undoing the effects of the getch method. */ void ungetc(int c) { if (c >= 0) { if (buffer_position > buffer) *--buffer_position = c; else ungetc_complicated(c); } } /** * The unread method may be used to reverse the effects of the read * method. The data is pushed into the buffer. Think of it as a * whole bunhs of ungetc calls (backwards). * * @param data * The base of the array of bytes to be returned. * @param nbytes * The number of bytes to be returned. */ void unread(const void *data, size_t nbytes); // ---------- V ------------------------------------------------------ // ---------- W ------------------------------------------------------ // ---------- X ------------------------------------------------------ // ---------- Y ------------------------------------------------------ // ---------- Z ------------------------------------------------------ protected: /** * The read_inner method is used to read unbuffered data from the * given input stream. At most \a nbytes bytes will be read into * \a data. The number of bytes actually read will be returned. * At end-of-file, a value <= 0 will be returned, and \a data will * be unchanged. All file read errors or format errors are fatal, * and will cause the method to not return. * * @param data * Where to put the results of the read. * @param nbytes * The maximum number of bytes to read. * @returns * The actual number of bytes read, or zero for end-of-file. */ virtual ssize_t read_inner(void *data, size_t nbytes) = 0; /** * The ftell_inner method is used to determine the unbuffered * current position within the input. */ virtual off_t ftell_inner(void) = 0; /** * The getc_complicated method is used to get a character from the * input. Usually users do not call this method directly, but * use the getch method instead. */ int getc_complicated(void); /** * The ungetc_complicated method is used to push a character back * onto an input. Usually users do not call this method directly, * but use the input_ungetc macro instead. */ void ungetc_complicated(int c); protected: /** * The default constructor. * For use by derived classes only. */ input(); private: // Do not use. input(const input &rhs); // Do not use. input &operator=(const input &rhs); /** * The buffer instance variable is used to remember the base of * a dynamically allocated array used to buffer the data for * buffered input. */ unsigned char *buffer; /** * The buffer_size instance variable is used to remember the * allocation size of the dynamically allocated buffer. */ size_t buffer_size; /** * The buffer_position instance variable is used to remember the * read position of the data within the buffer. */ unsigned char *buffer_position; /** * The buffer_end instance variable is used to remember the * highwater mark of data stored in the buffer. */ unsigned char *buffer_end; }; #endif // LIBAEGIS_INPUT_H // vim: set ts=8 sw=4 et :