#ifndef File_h #define File_h #include enum FileOrigin { beginning = SEEK_SET, cursor = SEEK_CUR, ending = SEEK_END }; /** @class File A File is a wrapper of a FILE* object. This class pretends to easy the work with C files. Example of usage: @code @endcode */ class File { private: /// A File object is a wrapper of this FILE* object. FILE* file; /// Stores the name of a file if it is already open, otherwise this pointer is null. /// This is an internal copy of the original filename char* filename; /// A copy of the mode used to open the file, NULL if no file is open char* mode; /// A buffer of dynamic allocated memory, used to read lines from text files char* buffer; /// The current allocated capacity of the buffer to read lines size_t bufferSize; public: // ToDo: Improve Doxygen documentation /// Default constructor. Creates an emtpy object that is not associated with a existing file File(); /// Constructor sobrecargado que intenta abrir el archivo cuyo nombre y modo de apertura son dados por parámetro. Si hay un error con la apertura, no se indicará al llamador; éste podrá veficarlo posteriormente con alguno de los métodos de reporte de estado. explicit File(const char* filename, const char* mode = "r"); /// Works with an already open file. It will be not closed when the File object is deleted explicit File(FILE* openFile); /// Destructor. Cierra el archivo si está abierto y elimina cualquier memoria dinámica relacionada con el archivo que estuviera en uso. ~File(); /// Abre el archivo cuyo nombre es dado por el parámetro filename. Retorna true en caso de éxito, false en caso contrario. bool open(const char* filename, const char* mode = "r"); /// Retorna true si el objeto File tiene un archivo abierto. inline bool isOpened() const { return file; } /// Operador de conversión a booleano. Retorna true si el objeto File tiene un archivo abierto. inline operator bool() const { return file; } /// Retorna true si el objeto File no tiene un archivo abierto. inline bool operator!() const { return ! file; } /// Cierra el archivo y libera los recursos en memoria asociados con él. Retorna true en caso de éxito, false en caso contrario. bool close(); /// Retorna el nombre del archivo, NULL si no hay uno abierto. inline const char* getFilename() const { return filename; } /// Retorna el modo con que se abrió el archivo, NULL si no está abierto. inline const char* getMode() const { return mode; } /// Imprime una cantidad arbitraria de parámetros en el archivo siguiendo las reglas de formato indicadas en el parámetro format. Retorna true en caso de éxito, false en caso contrario. bool printf(const char* format, ...); /// Lee una cantidad arbitraria de valores y los aloja en la memoria indicada por punteros, uno por cada parámetro bajo el control de la cadena con formato format. Retorna true en caso de éxito, false en caso de error o fin de archivo. bool scanf(const char* format, ...); /// Retorna el siguiente carácter en el archivo o EOF en caso de error o fin de archivo. int getc(); /// Escribe el carácter ch en el archivo. Retorna true en caso de éxito, false en caso contrario. bool putc(int ch); /// En caso de error, fin de archivo o insuficiente memoria, retorna NULL. Esto implica que si readLine() retorna un puntero no nulo, el llamador puede tener confianza de que la línea completa se ha leído del archivo. Si se provee un puntero como parámetro, se regresará en él la cantidad de caracteres leídos del archivo. Sugerencia: implemente este método leyendo un carácter a la vez desde el archivo. /// Lee los siguientes caracteres en el archivo hasta encontrar el carácter fin de línea ('\n'), el cual no se incluye en la cadena resultado. Retorna un puntero hacia un buffer en memoria dinámica manejado internamente por la clase File. Este buffer tendrá vigencia mientras no se haga otra invocación a readLine(); const char* readLine(size_t* length = NULL); /// Lee a lo sumo los siguientes size - 1 caracteres del archivo y los escribe en buffer. Se detiene al encontrar el carácter fin de línea ('\n') el cual es incluido en buffer. Retorna true en caso de éxito, false en caso de error o fin de archivo. bool gets(char* buffer, size_t size); /// Escribe la cadena str en el archivo. Retorna true en caso de éxito, false en caso de error. bool puts(const char* str); /// Lee del archivo elementCount elementos cada uno de tamaño elementSize bytes y los aloja en el arreglo arr. Retorna la cantidad de elementos leídos del archivo, la cual puede ser menor de la esperada. Debe utilizarse los métodos eof() o error() para determinar la causa. size_t read(void *arr, size_t elementSize, size_t elementCount); /// Escribe en el archivo elementCount elementos de tamaño elementSize bytes de cada uno, los cuales están alojados en el arreglo arr. Retorna la cantidad de elementos escritos en el archivo, la cual podría ser menor que elementCount en caso de error. size_t write(const void *arr, size_t elementSize, size_t elementCount); /// Envía al archivo los datos que están aún pendientes de escritura en el buffer del archivo. El resultado es indefinido si el archivo es de lectura. Retorna true en caso de éxito, false en caso contrario. bool flush(); /// Retorna la posición del cursor del archivo medido como la cantidad de bytes desde el inicio del mismo. En caso de error retorna -1. long tell() const; /// Retorna true en caso de éxito, false en caso de error. /// Mueve el cursor del archivo a la posición indicada medida en cantidad de bytes. Subsecuentes lecturas o escrituras se harán a partir de esta nueva posición. El valor de position es relativo al origen dado, el cual es una enumeración para indicar: el inicio del archivo (beginning), la posición actual del archivo (current), o el final del archivo (ending); bool seek(long position, FileOrigin origin = beginning); /// Mueve el cursor del archivo al inicio del mismo y limpia los códigos de estado de error. Retorna true en caso de éxito, false en caso de error o fin de archivo. bool rewind(); /// Retorna true si la última operación de lectura no pudo completarse a causa de encontrar el final del archivo. bool eof() const; /// Retorna true si en la última operación se produjo un error de entrada o salida. bool error() const; /// Limpia los indicadores de error y fin de archivo. void clearerr(); /// Escribe el booleano value en el archivo como un número: 0 para indicar false y 1 para indicar true. Retorna el archivo mismo. File& operator<<(bool value); /// Escribe el carácter ch en el archivo. Retorna el archivo mismo. File& operator<<(char ch); /// Escribe el entero con signo value en el archivo en formato de texto. Retorna el archivo mismo. File& operator<<(int value); /// Escribe el entero sin signo value en el archivo en formato de texto. Retorna el archivo mismo. File& operator<<(unsigned int value); /// Escribe el entero largo con signo value en el archivo en formato de texto. Retorna el archivo mismo. File& operator<<(long value); /// Escribe el entero largo sin signo value en el archivo en formato de texto. Retorna el archivo mismo. File& operator<<(unsigned long int value); /// Escribe el entero doblemente largo con signo value en el archivo en formato de texto. Retorna el archivo mismo. File& operator<<(long long value); /// Escribe el entero doblemente largo sin signo value en el archivo en formato de texto. Retorna el archivo mismo. File& operator<<(unsigned long long int value); /// Escribe el flotante value en el archivo en formato de texto. Retorna el archivo mismo. File& operator<<(double value); /// Escribe la cadena de caracteres str en el archivo. Retorna el archivo mismo. File& operator<<(const char* str); /// Lee un valor booleano del archivo y lo escribe en value. Retorna el archivo mismo. File& operator>>(bool& value); /// Lee un carácter del archivo y lo escribe en ch. Retorna el archivo mismo. File& operator>>(char& ch); /// Lee un valor entero con signo del archivo y lo escribe en value. Retorna el archivo mismo. File& operator>>(int& value); /// Lee un valor entero sin signo del archivo y lo escribe en value. Retorna el archivo mismo. File& operator>>(unsigned int& value); /// Lee un valor entero largo con signo del archivo y lo escribe en value. Retorna el archivo mismo. File& operator>>(long int& value); /// Lee un valor entero largo sin signo del archivo y lo escribe en value. Retorna el archivo mismo. File& operator>>(unsigned long int& value); /// Lee un valor entero doblemente largo con signo del archivo y lo escribe en value. Retorna el archivo mismo. File& operator>>(long long int& value); /// Lee un valor entero doblemente largo sin signo del archivo y lo escribe en value. Retorna el archivo mismo. File& operator>>(unsigned long long int& value); /// Lee un valor flotante del archivo y lo escribe en value. Retorna el archivo mismo. File& operator>>(double& value); public: /// Elimina el archivo cuya ruta y nombre es dada por el parámetro filename. Retorna true si el archivo pudo ser eliminado, false en caso de error. static bool remove(const char* filename); /// Renombra el archivo oldFilename a newFilename. El resultado es dependiente del sistema operativo si ya existe un archivo o directorio con nombre newFilaname. Retorna true si el archivo pudo ser renombrado, false en caso de error. static bool rename(const char* oldFilename, const char* newFilename); private: /// Private copy constructor: File objects must be not copied File(const File&); /// Private assignment operator: File objects must be not copied const File& operator=(const File&); /// Increases the capacity of the internal buffer to read lines bool increaseBufferCapacity(); }; #endif // File_h