2013-03-14 04:49:45 -07:00
/* 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"
2013-07-31 01:16:20 -07:00
# include "eina_list.h"
2015-10-16 06:14:22 -07:00
# include "eina_util.h"
2013-03-14 04:49:45 -07:00
2013-11-20 03:06:50 -08:00
# define EINA_FILE_MAGIC 0xFEEDBEEF
2014-03-20 00:35:41 -07:00
/**
* @ addtogroup Eina_Tools_Group Tools
*
* @ {
*/
/**
* @ addtogroup Eina_File_Group File
*
* @ brief Functions to handle files and directories .
*
2015-04-09 22:13:11 -07:00
* This module performs internal housekeeping and utility tasks for Eina_File .
2014-03-20 00:35:41 -07:00
* It also provides the underlying data types for things like file handles , file
2015-04-09 22:13:11 -07:00
* maps and file iterators .
2014-03-20 00:35:41 -07:00
*
* @ {
*/
2015-04-09 22:13:11 -07:00
/**
2014-03-20 00:35:41 -07:00
* @ typedef Eina_File_Map
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
* Type definition for an Eina File Map .
2015-04-09 22:13:11 -07:00
*
*/
2013-03-14 04:49:45 -07:00
typedef struct _Eina_File_Map Eina_File_Map ;
2014-03-20 00:35:41 -07:00
/**
* @ typedef Eina_Lines_Iterator
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
* Type definition for an Eina Lines Iterator .
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
*/
2013-03-14 04:49:45 -07:00
typedef struct _Eina_Lines_Iterator Eina_Lines_Iterator ;
2014-03-20 00:35:41 -07:00
/**
* @ struct _Eina_File
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
* This is the underlying data structure that represents a file in Eina .
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
*/
2013-03-14 04:49:45 -07:00
struct _Eina_File
{
2014-03-20 00:35:41 -07:00
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. */
2013-03-14 04:49:45 -07:00
# ifndef _WIN32
2014-03-20 00:35:41 -07:00
unsigned long long length ; /**< The length of the file in bytes. */
time_t mtime ; /**< The last modified time. */
ino_t inode ; /**< The inode. */
2013-03-14 04:49:45 -07:00
# ifdef _STAT_VER_LINUX
2014-03-20 00:35:41 -07:00
unsigned long int mtime_nsec ; /**< The nano version of the last modified time. */
2013-03-14 04:49:45 -07:00
# endif
# else
2014-03-20 00:35:41 -07:00
ULONGLONG length ; /**< The length of the file in bytes. */
ULONGLONG mtime ; /**< The last modified time. */
2013-03-14 04:49:45 -07:00
# endif
2014-03-20 00:35:41 -07:00
int refcount ; /**< Keeps track of references to #map. */
int global_refcount ; /**< Keeps track of references to #global_map. */
2013-03-14 04:49:45 -07:00
# ifndef _WIN32
2014-03-20 00:35:41 -07:00
int fd ; /**< The file descriptor. */
2013-03-14 04:49:45 -07:00
# else
2014-03-20 00:35:41 -07:00
HANDLE handle ; /**< A Win32 file handle for this file. */
2013-03-14 04:49:45 -07:00
# endif
2014-03-20 00:35:41 -07:00
Eina_List * dead_map ; /**< Tracks regions that get a failure from mmap(2). */
2013-07-31 01:16:20 -07:00
2014-03-20 00:35:41 -07:00
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 */
2017-09-14 22:38:29 -07:00
Eina_Bool global_hugetlb : 1 ; /**< Indicates whether #global_map uses HugeTLB */
2014-03-20 00:35:41 -07:00
Eina_Bool virtual : 1 ; /**< Indicates that this is a virtual file */
2017-07-06 19:19:31 -07:00
Eina_Bool copied : 1 ; /**< Indicates whether this file has copied data */
2013-03-14 04:49:45 -07:00
} ;
2014-03-20 00:35:41 -07:00
/**
* @ struct _Eina_File_Map
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
* This represents a memory mapped region of a file .
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
*/
2013-03-14 04:49:45 -07:00
struct _Eina_File_Map
{
2014-03-20 00:35:41 -07:00
void * map ; /**< A pointer to the mapped region */
2013-03-14 04:49:45 -07:00
2014-03-20 00:35:41 -07:00
unsigned long int offset ; /**< The offset in the file */
unsigned long int length ; /**< The length of the region */
2013-03-14 04:49:45 -07:00
2014-03-20 00:35:41 -07:00
int refcount ; /**< Tracks references to this region */
2013-03-14 04:49:45 -07:00
2014-03-20 00:35:41 -07:00
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). */
2013-03-14 04:49:45 -07:00
} ;
2014-03-20 00:35:41 -07:00
/**
* @ struct _Eina_Lines_Iterator
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
* This represents a line iterator a file .
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
*/
2013-03-14 04:49:45 -07:00
struct _Eina_Lines_Iterator
{
2015-04-09 22:13:11 -07:00
Eina_Iterator iterator ; /**< The iterator itself */
2013-03-14 04:49:45 -07:00
2014-03-20 00:35:41 -07:00
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). */
2013-03-14 04:49:45 -07:00
2014-03-20 00:35:41 -07:00
int boundary ; /**< Curretnly hard coded to 4096. */
2013-03-14 04:49:45 -07:00
2014-03-20 00:35:41 -07:00
Eina_File_Line current ; /**< The current line */
2013-03-14 04:49:45 -07:00
} ;
2014-03-20 00:35:41 -07:00
2013-03-15 00:05:05 -07:00
# ifndef EINA_LOG_COLOR_DEFAULT
2014-03-20 00:35:41 -07:00
/** Set the color for Eina log entries */
2013-03-15 00:05:05 -07:00
# define EINA_LOG_COLOR_DEFAULT EINA_COLOR_CYAN
# endif
# ifdef ERR
# undef ERR
# endif
2014-03-20 00:35:41 -07:00
/** Macro for logging Eina errors */
2013-03-15 00:05:05 -07:00
# define ERR(...) EINA_LOG_DOM_ERR(_eina_file_log_dom, __VA_ARGS__)
# ifdef WRN
# undef WRN
# endif
2014-03-20 00:35:41 -07:00
/** Macro for logging Eina warnings */
2013-03-15 00:05:05 -07:00
# define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__)
# ifdef INF
# undef INF
# endif
2014-03-20 00:35:41 -07:00
/** Macro for logging Eina info messages */
2013-03-15 00:05:05 -07:00
# define INF(...) EINA_LOG_DOM_INFO(_eina_file_log_dom, __VA_ARGS__)
# ifdef DBG
# undef DBG
# endif
2014-03-20 00:35:41 -07:00
/** Macro for logging Eina debug messages */
2013-03-15 00:05:05 -07:00
# define DBG(...) EINA_LOG_DOM_DBG(_eina_file_log_dom, __VA_ARGS__)
2014-03-20 00:35:41 -07:00
/**
* @ brief Determines if a path is relative or absolute .
2015-04-09 22:13:11 -07:00
* The implementation simply chekcs if the fist char in the path is ' / ' . If it
* is not , the path is considered relative .
2014-03-20 00:35:41 -07:00
*
* @ param path The path to check .
2013-03-15 00:05:05 -07:00
2014-03-20 00:35:41 -07:00
* @ return EINA_TRUE if the path is relative , EINA_FALSE otherwise .
*
*/
2013-03-14 04:49:45 -07:00
Eina_Bool eina_file_path_relative ( const char * path ) ;
2014-03-20 00:35:41 -07:00
/**
2015-04-09 22:13:11 -07:00
* @ 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
2014-03-20 00:35:41 -07:00
* relative path .
*
* @ param path The path to append to the current directory .
* @ param len The length of @ p path .
2015-04-09 22:13:11 -07:00
*
2014-03-20 00:35:41 -07:00
* @ return A pointer to a string that contains the absolute path to the current
2015-04-09 22:13:11 -07:00
* working directory plus any path you send in .
2014-03-20 00:35:41 -07:00
*
*/
2013-03-14 04:49:45 -07:00
Eina_Tmpstr * eina_file_current_directory_get ( const char * path , size_t len ) ;
2014-03-20 00:35:41 -07:00
/**
* @ brief Cleans up Eina after a file is no longer needed .
*
* @ param path The path of the file .
2015-04-09 22:13:11 -07:00
*
* @ return On success , it will return the @ p path string . If @ p path is @ c NULL ,
2014-03-20 00:35:41 -07:00
* it will return and empty string .
*
*/
2013-03-14 04:49:45 -07:00
char * eina_file_cleanup ( Eina_Tmpstr * path ) ;
2014-03-20 00:35:41 -07:00
/**
2015-04-09 22:13:11 -07:00
* @ brief Closes and cleans up after an Eina file .
2014-03-20 00:35:41 -07:00
*
* @ param file The path of the file .
*
*/
2013-11-20 03:06:50 -08:00
void eina_file_clean_close ( Eina_File * file ) ;
2014-03-20 00:35:41 -07:00
/**
* @ brief Closes a file from the OS perspective .
*
* @ param file The path of the file .
*
*/
2013-03-14 04:49:45 -07:00
void eina_file_real_close ( Eina_File * file ) ;
2014-03-20 00:35:41 -07:00
/**
* @ brief Resets the internal housekeeping structures after a file has changed .
* Despite the name , this routine does not write anything to disk . It invalidates
2015-04-09 22:13:11 -07:00
* the memory maps for the file . If the file has shrunk , it also adds any mapped
2014-03-20 00:35:41 -07:00
* regions past the end of the file to the dead_map .
*
* @ param file The file .
* @ param length The current length of the file after the change .
*
2015-04-09 22:13:11 -07:00
*/
2013-07-31 01:16:20 -07:00
void eina_file_flush ( Eina_File * file , unsigned long int length ) ;
2014-03-20 00:35:41 -07:00
/**
* @ 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
2015-04-09 22:13:11 -07:00
* housekeeping and free the resources associated with it . In the case where
2014-03-20 00:35:41 -07:00
* the map is part of the dead_map , @ p free_func will be called to handle the actual
* deallocation .
*
* @ param file The file .
* @ param map The memory mapped region that is to be freed .
2015-04-09 22:13:11 -07:00
* @ param free_func A pointer to a function that will be called to free up the
* resources used by the map .
2014-03-20 00:35:41 -07:00
*
*/
2013-07-31 01:16:20 -07:00
void eina_file_common_map_free ( Eina_File * file , void * map ,
void ( * free_func ) ( Eina_File_Map * map ) ) ;
2014-03-20 00:35:41 -07:00
/** A pointer to the global Eina file cache. */
2013-03-14 04:49:45 -07:00
extern Eina_Hash * _eina_file_cache ;
2014-03-20 00:35:41 -07:00
/** The global file lock cache */
2013-03-14 04:49:45 -07:00
extern Eina_Lock _eina_file_lock_cache ;
2014-03-20 00:35:41 -07:00
/** The global Eina log file domain. */
2013-03-15 00:05:05 -07:00
extern int _eina_file_log_dom ;
2013-03-14 04:49:45 -07:00
2013-07-30 19:51:51 -07:00
// Common function to handle virtual file
2014-03-20 00:35:41 -07:00
/**
* @ brief Map the entire contents fo a virtual file to a buffer .
*
* @ param file The virtual file to map in memory
*
*/
2013-07-30 19:51:51 -07:00
void * eina_file_virtual_map_all ( Eina_File * file ) ;
2014-03-20 00:35:41 -07:00
/**
* @ brief Map a part of a virtual file to a buffer .
*
* @ param file The virtual file to map in memory
* @ param offset The offset inside the file to start mapping
* @ param length The length of the region to map
*
*/
2013-07-30 19:51:51 -07:00
void * eina_file_virtual_map_new ( Eina_File * file ,
unsigned long int offset , unsigned long int length ) ;
2014-03-20 00:35:41 -07:00
/**
* @ brief Unref and unmap memory if possible .
*
* @ param file The file handler to unmap memory from .
* @ param map Memory map to unref and unmap .
*
*/
2013-07-30 19:51:51 -07:00
void eina_file_virtual_map_free ( Eina_File * file , void * map ) ;
// Common hash function
2014-03-20 00:35:41 -07:00
/**
* @ brief Get the length of a map key .
2015-04-09 22:13:11 -07:00
* @ warning This function is not yet implemented . At present it ony returns
2014-03-20 00:35:41 -07:00
* @ code sizeof ( unsigned long int ) * 2 @ endcode
*
2015-04-09 22:13:11 -07:00
* @ param key The key for which length will be calcualted .
*
2014-03-20 00:35:41 -07:00
* @ return The length of the key .
*
*/
2013-07-30 19:51:51 -07:00
unsigned int eina_file_map_key_length ( const void * key ) ;
2014-03-20 00:35:41 -07:00
/**
* @ brief Compares two map keys .
2015-04-09 22:13:11 -07:00
* 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 .
2014-03-20 00:35:41 -07:00
*
* @ param key1 The first key .
2015-04-09 22:13:11 -07:00
* @ param key1_length The length of the first key .
2014-03-20 00:35:41 -07:00
* @ param key2 The second key .
2015-04-09 22:13:11 -07:00
* @ param key2_length The length of the second key .
*
2014-03-20 00:35:41 -07:00
* @ return Positive number if Key1 > Key2 , else a negative number . Will return
* zero if both elements of the key are exactly the same .
*
*/
2013-11-09 03:07:27 -08:00
int eina_file_map_key_cmp ( const unsigned long long int * key1 , int key1_length ,
const unsigned long long int * key2 , int key2_length ) ;
2014-03-20 00:35:41 -07:00
/**
* @ brief Creates a hash from a map key .
*
* @ param key A pointer to the key .
2015-04-09 22:13:11 -07:00
* @ param key_length The length of the key .
*
2014-03-20 00:35:41 -07:00
* @ return A key hash .
*
*/
2013-11-09 03:07:27 -08:00
int eina_file_map_key_hash ( const unsigned long long int * key , int key_length ) ;
2013-07-30 19:51:51 -07:00
2014-03-20 00:35:41 -07:00
/**
* @ }
*/
/**
* @ }
*/
2013-03-14 04:49:45 -07:00
# endif /* EINA_FILE_COMMON_H_ */