/** * Copyright 2013 (c) Anna Schumaker. */ #ifndef OCARINA_CORE_FILE_H #define OCARINA_CORE_FILE_H #include #include #include #define FILE_MAX_LEN 16 /** * Constants defining how files can be opened. */ enum OpenMode { OPEN_READ, /**< File is open for reading. */ OPEN_WRITE, /**< File is open for writing. */ }; /** * File data is store in the user's home directory according to the * XDG / freedesktop.org specification, meaning all of our data will * be stored in a subdirectory of $XDG_DATA_HOME. The actual subdirectory * changes based on what configuration values the user has set when Ocarina * is compiled. * * Config Value | Ocarina Directory * ---------------|-------------------- * default | $XDG_DATA_HOME/ocarina/ * CONFIG_DEBUG | $XDG_DATA_HOME/ocarina-debug/ * CONFIG_TESTING | $XDG_DATA_HOME/ocarina-test/ * * Data should be written to files using either a space or newline as a * delimiter. The beginning of every file is the current file version * followed by a newline. For example: * * 42 * * * * Data should be written to files using either a space or newline as * a delimiter. */ struct file { OpenMode f_mode; /* The file's current open mode. */ unsigned int f_version; /* The file's current data version. */ unsigned int f_prev; /* The file's on-disk data version. */ FILE *f_file; /* The file's IO stream. */ gchar f_name[FILE_MAX_LEN]; /* The file's basename. */ }; /* Initialize a new file object. */ void file_init(struct file *, const gchar *, unsigned int); /* * Returns the full path of the file or an empty string if filename is not set. * This function allocates a new string that MUST be freed with g_free(). */ gchar *file_path(struct file *); /* Returns the version number of the file. */ const unsigned int file_version(struct file *); /* Returns true if the file exists on disk and false otherwise. */ bool file_exists(struct file *); /* * Call to open a file for either reading or writing. Callers * are expected to call file_close() when IO is completed. * * When opening a file for reading (OPEN_READ): * - Check if the file exists. * - Read in file->_prev_version from the start of the file. * * When opening a file for writing (OPEN_WRITE): * - Create missing directories as needed. * - Write file->_version to the start of the file. * * Returns true if the open was successful and false otherwise. */ bool file_open(struct file *, OpenMode); /* Close an open file, setting file->f_file to NULL. */ void file_close(struct file *); /* Read an entire line from the file and return it to the caller. */ std::string file_readl(struct file *); /* * Read from a file with an fscanf(3) style format string. * Returns the number of items matched. */ int file_readf(struct file *, const char *, ...); /* * Write to a file with an fprintf(3) style format string. * Returns the number of bytes successfully written. */ int file_writef(struct file *, const char *, ...); #endif /* OCARINA_CORE_FILE_H */