efl/src/lib/eina/eina_file_common.h

351 lines
11 KiB
C

/* EINA - EFL data type library
* Copyright (C) 2013 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EINA_FILE_COMMON_H_
# define EINA_FILE_COMMON_H_
#include "eina_file.h"
#include "eina_tmpstr.h"
#include "eina_lock.h"
#include "eina_list.h"
#include "eina_util.h"
#define EINA_FILE_MAGIC 0xFEEDBEEF
/**
* @addtogroup Eina_Tools_Group Tools
*
* @{
*/
/**
* @addtogroup Eina_File_Group File
*
* @brief Functions to handle files and directories.
*
* This module performs internal housekeeping and utility tasks for Eina_File.
* It also provides the underlying data types for things like file handles, file
* maps and file iterators.
*
* @{
*/
/**
* @typedef Eina_File_Map
*
* Type definition for an Eina File Map.
*
*/
typedef struct _Eina_File_Map Eina_File_Map;
/**
* @typedef Eina_Lines_Iterator
*
* Type definition for an Eina Lines Iterator.
*
*/
typedef struct _Eina_Lines_Iterator Eina_Lines_Iterator;
/**
* @struct _Eina_File
*
* This is the underlying data structure that represents a file in Eina.
*
*/
struct _Eina_File
{
EINA_MAGIC; /**< Indicates whether Eina Magic should be used. */
const char *filename; /**< The absolute path of the file. Note that the path given when calling @ref eina_file_open will be run through @ref eina_file_path_sanitize before it is stored here. */
Eina_Hash *map; /**< Tracks portions of a file that have been mapped with mmap(2). The key is a tuple offset/length and the data is a pointer to the mapped region. */
Eina_Hash *rmap; /**< Similar function to #map, but used to look up mapped areas by pointer rather than offset/length. */
void *global_map; /**< A pointer to the entire contents of the file that have been mapped with mmap(2). This is the common case, and EFL and is optimized for it. */
Eina_Lock lock; /**< A file locking mechanism. */
#ifndef _WIN32
unsigned long long length; /**< The length of the file in bytes. */
time_t mtime; /**< The last modified time. */
ino_t inode; /**< The inode. */
#ifdef _STAT_VER_LINUX
unsigned long int mtime_nsec; /**< The nano version of the last modified time. */
#endif
#else
ULONGLONG length; /**< The length of the file in bytes. */
ULONGLONG mtime; /**< The last modified time. */
#endif
int refcount; /**< Keeps track of references to #map. */
int global_refcount; /**< Keeps track of references to #global_map. */
Eina_Statgen statgen;/**< For inexact stats a stat gen count to rate limit syscalls to stat file */
#ifndef _WIN32
int fd; /**< The file descriptor. */
#else
HANDLE handle; /**< A Win32 file handle for this file. */
#endif
Eina_List *dead_map; /**< Tracks regions that get a failure from mmap(2). */
Eina_Bool shared : 1; /**< Indicates whether this file can be shared */
Eina_Bool delete_me : 1; /**< Indicates that this file should be deleted */
Eina_Bool global_faulty : 1; /**< Indicates whether #global_map is bad */
Eina_Bool global_hugetlb : 1; /**< Indicates whether #global_map uses HugeTLB */
Eina_Bool virtual : 1; /**< Indicates that this is a virtual file */
Eina_Bool copied : 1; /**< Indicates whether this file has copied data */
};
/**
* @struct _Eina_File_Map
*
* This represents a memory mapped region of a file.
*
*/
struct _Eina_File_Map
{
void *map; /**< A pointer to the mapped region */
unsigned long int offset; /**< The offset in the file */
unsigned long int length; /**< The length of the region */
int refcount; /**< Tracks references to this region */
Eina_Bool hugetlb : 1; /**< Indicates if we are using HugeTLB */
Eina_Bool faulty : 1; /**< Indicates if this region was not mapped correctly (i.e. the call to mmap(2) failed). */
#ifdef _WIN32
void *ret; /**< A pointer to the mapped region */
#endif
};
/**
* @struct _Eina_Lines_Iterator
*
* This represents a line iterator a file.
*
*/
struct _Eina_Lines_Iterator
{
Eina_Iterator iterator; /**< The iterator itself */
Eina_File *fp; /**< The file this iterator is associated with */
const char *map; /**< A pointer to the head of the file that has been mapped with mmap(2). */
const char *end; /**< A pointer to the end of the file that has been mapped with mmap(2). */
int boundary; /**< Currently hard coded to 4096. */
Eina_File_Line current; /**< The current line */
};
#ifndef EINA_LOG_COLOR_DEFAULT
/** Set the color for Eina log entries */
#define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN
#endif
#ifdef ERR
#undef ERR
#endif
/** Macro for logging Eina errors */
#define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__)
#ifdef WRN
#undef WRN
#endif
/** Macro for logging Eina warnings */
#define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__)
#ifdef INF
#undef INF
#endif
/** Macro for logging Eina info messages */
#define INF(...) EINA_LOG_DOM_INFO(_eina_file_log_dom, __VA_ARGS__)
#ifdef DBG
#undef DBG
#endif
/** Macro for logging Eina debug messages */
#define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__)
/**
* @brief Determines if a path is relative or absolute.
* The implementation simply checks if the first char in the path is '/'. If it
* is not, the path is considered relative.
*
* @param[in] path The path to check.
*
* @return EINA_TRUE if the path is relative, EINA_FALSE otherwise.
*
*/
Eina_Bool eina_file_path_relative(const char *path);
/**
* @brief Gets the current directory and optionally appends a path to it.
* If a string was passed in via the @p path parameter, it will
* be appended to the current working directory. Presumably, this will be a
* relative path.
*
* @param[in] path The path to append to the current directory.
* @param[in] len The length of @p path.
*
* @return A pointer to a string that contains the absolute path to the current
* working directory plus any path you send in.
*
*/
Eina_Tmpstr *eina_file_current_directory_get(const char *path, size_t len);
/**
* @brief Cleans up Eina after a file is no longer needed.
*
* @param[in,out] path The path of the file.
*
* @return On success, it will return the @p path string. If @p path is @c NULL,
* it will return and empty string.
*
*/
char *eina_file_cleanup(Eina_Tmpstr *path);
/**
* @brief Closes and cleans up after an Eina file.
*
* @param[in,out] file The path of the file.
*
*/
void eina_file_clean_close(Eina_File *file);
/**
* @brief Closes a file from the OS perspective.
*
* @param[in,out] file The path of the file.
*
*/
void eina_file_real_close(Eina_File *file);
/**
* @brief Resets the internal housekeeping structures after a file has changed.
* Despite the name, this routine does not write anything to disk. It invalidates
* the memory maps for the file. If the file has shrunk, it also adds any mapped
* regions past the end of the file to the dead_map.
*
* @param[in,out] file The file.
* @param[in] length The current length of the file after the change.
*
*/
void eina_file_flush(Eina_File *file, unsigned long int length);
/**
* @brief Removes a mapped region from the file and frees the resources.
* This routine will remove a previously mapped region from the internal Eina File
* housekeeping and free the resources associated with it. In the case where
* the map is part of the dead_map, @p free_func will be called to handle the actual
* deallocation.
*
* @param[in,out] file The file.
* @param[in,out] map The memory mapped region that is to be freed.
* @param[in] free_func A pointer to a function that will be called to
* free up the resources used by the map.
*
*/
void eina_file_common_map_free(Eina_File *file, void *map,
void (*free_func)(Eina_File_Map *map));
/** A pointer to the global Eina file cache. */
extern Eina_Hash *_eina_file_cache;
/** The global file lock cache */
extern Eina_Lock _eina_file_lock_cache;
/** The global Eina log file domain. */
extern int _eina_file_log_dom;
// Common function to handle virtual file
/**
* @brief Map the entire contents of a virtual file to a buffer.
*
* @param[in] file The virtual file to map in memory
* @return The buffer
*/
void *eina_file_virtual_map_all(Eina_File *file);
/**
* @brief Map a part of a virtual file to a buffer.
*
* @param[in,out] file The virtual file to map in memory
* @param[in] offset The offset inside the file to start mapping
* @param[in] length The length of the region to map
* @return The buffer
*/
void *eina_file_virtual_map_new(Eina_File *file,
unsigned long int offset, unsigned long int length);
/**
* @brief Unref and unmap memory if possible.
*
* @param[in,out] file The file handler to unmap memory from.
* @param[in,out] map Memory map to unref and unmap.
*
*/
void eina_file_virtual_map_free(Eina_File *file, void *map);
// Common hash function
/**
* @brief Get the length of a map key.
* @warning This function is not yet implemented. At present it only returns
* @code sizeof (unsigned long int) * 2 @endcode
*
* @param[in] key The key for which length will be calculated.
*
* @return The length of the key.
*
*/
unsigned int eina_file_map_key_length(const void *key);
/**
* @brief Compares two map keys.
* The implementation assumes that @p key1 and @p key2 are both pointers to an
* array with 2 elements, as is the case with the Eina file map keys.
*
* @param[in] key1 The first key.
* @param[in] key1_length The length of the first key.
* @param[in] key2 The second key.
* @param[in] key2_length The length of the second key.
*
* @return Positive number if Key1 > Key2, else a negative number. Will return
* zero if both elements of the key are exactly the same.
*
*/
int eina_file_map_key_cmp(const unsigned long long int *key1, int key1_length,
const unsigned long long int *key2, int key2_length);
/**
* @brief Creates a hash from a map key.
*
* @param[in] key A pointer to the key.
* @param[in] key_length The length of the key.
*
* @return A key hash.
*
*/
int eina_file_map_key_hash(const unsigned long long int *key, int key_length);
/**
* @}
*/
/**
* @}
*/
#endif /* EINA_FILE_COMMON_H_ */