2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* file_access.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2022-01-13 09:45:09 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2014-02-10 02:10:30 +01:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# ifndef FILE_ACCESS_H
# define FILE_ACCESS_H
2018-09-11 18:13:45 +02:00
# include "core/math/math_defs.h"
# include "core/os/memory.h"
# include "core/typedefs.h"
# include "core/ustring.h"
2014-02-10 02:10:30 +01:00
/**
* Multi - Platform abstraction for accessing to files .
*/
class FileAccess {
public :
enum AccessType {
ACCESS_RESOURCES ,
ACCESS_USERDATA ,
ACCESS_FILESYSTEM ,
ACCESS_MAX
} ;
2017-03-05 16:44:50 +01:00
typedef void ( * FileCloseFailNotify ) ( const String & ) ;
2016-06-13 15:10:50 +02:00
2017-03-05 16:44:50 +01:00
typedef FileAccess * ( * CreateFunc ) ( ) ;
2014-02-10 02:10:30 +01:00
bool endian_swap ;
bool real_is_double ;
2019-04-07 20:46:52 +02:00
virtual uint32_t _get_unix_permissions ( const String & p_file ) = 0 ;
virtual Error _set_unix_permissions ( const String & p_file , uint32_t p_permissions ) = 0 ;
2017-03-05 16:44:50 +01:00
protected :
2022-08-24 20:06:03 +02:00
AccessType get_access_type ( ) const ;
2017-03-05 16:44:50 +01:00
String fix_path ( const String & p_path ) const ;
virtual Error _open ( const String & p_path , int p_mode_flags ) = 0 ; ///< open a file
virtual uint64_t _get_modified_time ( const String & p_file ) = 0 ;
2014-02-10 02:10:30 +01:00
2016-06-13 15:10:50 +02:00
static FileCloseFailNotify close_fail_notify ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
private :
2014-02-10 02:10:30 +01:00
static bool backup_save ;
AccessType _access_type ;
static CreateFunc create_func [ ACCESS_MAX ] ; /** default file access creation function for a platform */
2017-03-05 16:44:50 +01:00
template < class T >
static FileAccess * _create_builtin ( ) {
return memnew ( T ) ;
2014-02-10 02:10:30 +01:00
}
public :
2017-03-05 16:44:50 +01:00
static void set_file_close_fail_notify_callback ( FileCloseFailNotify p_cbk ) { close_fail_notify = p_cbk ; }
2016-06-13 15:10:50 +02:00
2014-02-10 02:10:30 +01:00
virtual void _set_access_type ( AccessType p_access ) ;
2017-03-05 16:44:50 +01:00
enum ModeFlags {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
READ = 1 ,
WRITE = 2 ,
READ_WRITE = 3 ,
WRITE_READ = 7 ,
2014-02-10 02:10:30 +01:00
} ;
2017-03-05 16:44:50 +01:00
virtual void close ( ) = 0 ; ///< close a file
virtual bool is_open ( ) const = 0 ; ///< true when file is open
2014-02-10 02:10:30 +01:00
2018-03-09 15:45:21 +01:00
virtual String get_path ( ) const { return " " ; } /// returns the path for the current open file
virtual String get_path_absolute ( ) const { return " " ; } /// returns the absolute path for the current open file
2019-03-26 18:51:13 +01:00
virtual void seek ( uint64_t p_position ) = 0 ; ///< seek to a given position
virtual void seek_end ( int64_t p_position = 0 ) = 0 ; ///< seek from the end of file with negative offset
virtual uint64_t get_position ( ) const = 0 ; ///< get position in the file
virtual uint64_t get_len ( ) const = 0 ; ///< get size of the file
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
virtual bool eof_reached ( ) const = 0 ; ///< reading passed EOF
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
virtual uint8_t get_8 ( ) const = 0 ; ///< get a byte
2016-03-09 00:00:52 +01:00
virtual uint16_t get_16 ( ) const ; ///< get 16 bits uint
virtual uint32_t get_32 ( ) const ; ///< get 32 bits uint
virtual uint64_t get_64 ( ) const ; ///< get 64 bits uint
2014-02-10 02:10:30 +01:00
virtual float get_float ( ) const ;
virtual double get_double ( ) const ;
virtual real_t get_real ( ) const ;
2019-03-26 18:51:13 +01:00
virtual uint64_t get_buffer ( uint8_t * p_dst , uint64_t p_length ) const ; ///< get an array of bytes
2014-02-10 02:10:30 +01:00
virtual String get_line ( ) const ;
2017-05-29 02:46:48 +02:00
virtual String get_token ( ) const ;
2018-11-13 12:53:24 +01:00
virtual Vector < String > get_csv_line ( const String & p_delim = " , " ) const ;
2022-07-31 18:46:53 +02:00
virtual String get_as_utf8_string ( bool p_skip_cr = true ) const ; // Skip CR by default for compat.
2016-03-09 00:00:52 +01:00
2014-02-10 02:10:30 +01:00
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
* It ' s not about the current CPU type but file formats .
* this flags get reset to false ( little endian ) on each open
*/
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
virtual void set_endian_swap ( bool p_swap ) { endian_swap = p_swap ; }
2014-02-10 02:10:30 +01:00
inline bool get_endian_swap ( ) const { return endian_swap ; }
2017-03-05 16:44:50 +01:00
virtual Error get_error ( ) const = 0 ; ///< get last error
2014-02-10 02:10:30 +01:00
2017-09-22 07:56:02 +02:00
virtual void flush ( ) = 0 ;
2017-03-05 16:44:50 +01:00
virtual void store_8 ( uint8_t p_dest ) = 0 ; ///< store a byte
2016-03-09 00:00:52 +01:00
virtual void store_16 ( uint16_t p_dest ) ; ///< store 16 bits uint
virtual void store_32 ( uint32_t p_dest ) ; ///< store 32 bits uint
virtual void store_64 ( uint64_t p_dest ) ; ///< store 64 bits uint
2014-02-10 02:10:30 +01:00
virtual void store_float ( float p_dest ) ;
virtual void store_double ( double p_dest ) ;
virtual void store_real ( real_t p_real ) ;
2017-03-05 16:44:50 +01:00
virtual void store_string ( const String & p_string ) ;
2017-08-11 21:10:05 +02:00
virtual void store_line ( const String & p_line ) ;
2018-11-13 12:53:24 +01:00
virtual void store_csv_line ( const Vector < String > & p_values , const String & p_delim = " , " ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
virtual void store_pascal_string ( const String & p_string ) ;
2014-03-14 02:57:24 +01:00
virtual String get_pascal_string ( ) ;
2019-03-26 18:51:13 +01:00
virtual void store_buffer ( const uint8_t * p_src , uint64_t p_length ) ; ///< store an array of bytes
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
virtual bool file_exists ( const String & p_name ) = 0 ; ///< return true if a file exists
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
virtual Error reopen ( const String & p_path , int p_mode_flags ) ; ///< does not change the AccessType
2014-02-10 02:10:30 +01:00
static FileAccess * create ( AccessType p_access ) ; /// Create a file access (for the current platform) this is the only portable way of accessing files.
2017-03-05 16:44:50 +01:00
static FileAccess * create_for_path ( const String & p_path ) ;
2021-05-04 16:00:45 +02:00
static FileAccess * open ( const String & p_path , int p_mode_flags , Error * r_error = nullptr ) ; /// Create a file access (for the current platform) this is the only portable way of accessing files.
2014-02-10 02:10:30 +01:00
static CreateFunc get_create_func ( AccessType p_access ) ;
2017-03-05 16:44:50 +01:00
static bool exists ( const String & p_name ) ; ///< return true if a file exists
static uint64_t get_modified_time ( const String & p_file ) ;
2019-04-07 20:46:52 +02:00
static uint32_t get_unix_permissions ( const String & p_file ) ;
static Error set_unix_permissions ( const String & p_file , uint32_t p_permissions ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
static void set_backup_save ( bool p_enable ) { backup_save = p_enable ; } ;
2014-02-10 02:10:30 +01:00
static bool is_backup_save_enabled ( ) { return backup_save ; } ;
2017-03-05 16:44:50 +01:00
static String get_md5 ( const String & p_file ) ;
static String get_sha256 ( const String & p_file ) ;
2017-12-27 19:21:18 +01:00
static String get_multiple_md5 ( const Vector < String > & p_file ) ;
2014-02-10 02:10:30 +01:00
2021-05-04 16:00:45 +02:00
static Vector < uint8_t > get_file_as_array ( const String & p_path , Error * r_error = nullptr ) ;
static String get_file_as_string ( const String & p_path , Error * r_error = nullptr ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
template < class T >
2014-02-10 02:10:30 +01:00
static void make_default ( AccessType p_access ) {
2017-03-05 16:44:50 +01:00
create_func [ p_access ] = _create_builtin < T > ;
2014-02-10 02:10:30 +01:00
}
FileAccess ( ) ;
2017-03-05 16:44:50 +01:00
virtual ~ FileAccess ( ) { }
2014-02-10 02:10:30 +01:00
} ;
struct FileAccessRef {
2017-03-05 16:44:50 +01:00
_FORCE_INLINE_ FileAccess * operator - > ( ) {
2014-02-10 02:10:30 +01:00
return f ;
}
2021-05-04 16:00:45 +02:00
operator bool ( ) const { return f ! = nullptr ; }
2014-02-10 02:10:30 +01:00
FileAccess * f ;
2017-09-13 09:13:23 +02:00
operator FileAccess * ( ) { return f ; }
2014-02-10 02:10:30 +01:00
FileAccessRef ( FileAccess * fa ) { f = fa ; }
2022-03-23 06:53:32 +01:00
FileAccessRef ( FileAccessRef & & other ) {
f = other . f ;
other . f = nullptr ;
}
2017-03-05 16:44:50 +01:00
~ FileAccessRef ( ) {
2021-05-05 12:44:11 +02:00
if ( f ) {
2021-05-04 14:28:27 +02:00
memdelete ( f ) ;
2021-05-05 12:44:11 +02:00
}
2017-03-05 16:44:50 +01:00
}
2014-02-10 02:10:30 +01:00
} ;
2022-07-25 12:33:41 +02:00
# endif // FILE_ACCESS_H