LCOV - code coverage report
Current view: top level - asar - virtualfile.cpp (source / functions) Coverage Total Hit
Test: asar build #66 Lines: 67.6 % 142 96
Test Date: 2024-01-16 02:45:19 Functions: 67.7 % 31 21
Branches: 62.1 % 95 59

             Branch data     Line data    Source code
       1                 :             : #include <errno.h>
       2                 :             : #include "virtualfile.h"
       3                 :             : #include "platform/file-helpers.h"
       4                 :             : #include "warnings.h"
       5                 :             : 
       6                 :             : class virtual_file
       7                 :             : {
       8                 :             : public:
       9                 :         266 :         virtual ~virtual_file()
      10                 :         266 :         {
      11                 :         266 :         }
      12                 :             : 
      13                 :             :         virtual void close() = 0;
      14                 :             : 
      15                 :             :         virtual size_t read(void* out_buffer, size_t pos, size_t num_bytes) = 0;
      16                 :             : 
      17                 :             :         virtual size_t get_size() = 0;
      18                 :             : };
      19                 :             : 
      20                 :             : class memory_file : public virtual_file
      21                 :             : {
      22                 :             : public:
      23                 :           0 :         memory_file(const void* data, size_t length)
      24                 :           0 :                 : m_data(data), m_length(length)
      25                 :             :         {
      26                 :           0 :         }
      27                 :             : 
      28                 :           0 :         virtual ~memory_file()
      29                 :           0 :         {
      30                 :           0 :                 close();
      31                 :           0 :         }
      32                 :             : 
      33                 :           0 :         virtual void close()
      34                 :             :         {
      35                 :           0 :         }
      36                 :             : 
      37                 :           0 :         virtual size_t read(void* out_buffer, size_t pos, size_t num_bytes)
      38                 :             :         {
      39         [ #  # ]:           0 :                 if(pos > m_length) return 0;
      40                 :             : 
      41                 :           0 :                 int diff = (int)(pos + num_bytes) - (int)m_length;
      42                 :           0 :                 num_bytes -= diff < 0 ? 0 : (unsigned int)diff;
      43                 :             : 
      44                 :           0 :                 memcpy(out_buffer, (const char*)m_data + pos, num_bytes);
      45                 :           0 :                 return num_bytes;
      46                 :             :         }
      47                 :             : 
      48                 :           0 :         virtual size_t get_size()
      49                 :             :         {
      50                 :           0 :                 return m_length;
      51                 :             :         }
      52                 :             : 
      53                 :             : private:
      54                 :             :         const void* m_data;
      55                 :             :         size_t m_length;
      56                 :             : };
      57                 :             : 
      58                 :             : class physical_file : public virtual_file
      59                 :             : {
      60                 :             : public:
      61                 :         266 :         physical_file()
      62                 :         532 :                 : m_file_handle(InvalidFileHandle)
      63                 :             :         {
      64                 :         266 :         }
      65                 :             : 
      66                 :        1064 :         virtual ~physical_file()
      67                 :         532 :         {
      68                 :         532 :                 close();
      69                 :        1064 :         }
      70                 :             : 
      71                 :         532 :         virtual_file_error open(const string& path)
      72                 :             :         {
      73         [ +  - ]:         532 :                 if (path != "")
      74                 :             :                 {
      75                 :             :                         // randomdude999: checking this before file regularity to improve error messages
      76   [ +  +  +  + ]:         532 :                         if(!file_exists((const char*)path)) return vfe_doesnt_exist;
      77   [ +  +  +  + ]:         516 :                         if(!check_is_regular_file((const char*)path)) return vfe_not_regular_file;
      78                 :             : 
      79                 :         504 :                         FileOpenError error = FileOpenError_None;
      80                 :             : 
      81                 :         504 :                         m_file_handle = open_file((const char*)path, FileOpenMode_Read, &error);
      82                 :             : 
      83         [ -  + ]:         504 :                         if (m_file_handle == InvalidFileHandle)
      84                 :             :                         {
      85         [ #  # ]:           0 :                                 if (error == FileOpenError_NotFound)
      86                 :             :                                 {
      87                 :           0 :                                         return vfe_doesnt_exist;
      88                 :             :                                 }
      89         [ #  # ]:           0 :                                 else if (error == FileOpenError_AccessDenied)
      90                 :             :                                 {
      91                 :           0 :                                         return vfe_access_denied;
      92                 :             :                                 }
      93                 :             :                                 else
      94                 :             :                                 {
      95                 :           0 :                                         return vfe_unknown;
      96                 :             :                                 }
      97                 :             :                         }
      98                 :             : 
      99                 :         252 :                         return vfe_none;
     100                 :             :                 }
     101                 :             : 
     102                 :           0 :                 return vfe_doesnt_exist;
     103                 :             :         }
     104                 :             : 
     105                 :        1036 :         virtual void close()
     106                 :             :         {
     107         [ +  + ]:        1036 :                 if (m_file_handle != InvalidFileHandle)
     108                 :             :                 {
     109                 :         504 :                         close_file(m_file_handle);
     110                 :         504 :                         m_file_handle = InvalidFileHandle;
     111                 :             :                 }
     112                 :        1036 :         }
     113                 :             : 
     114                 :         518 :         virtual size_t read(void* out_buffer, size_t pos, size_t num_bytes)
     115                 :             :         {
     116                 :         518 :                 set_file_pos(m_file_handle, (uint64_t)pos);
     117                 :         518 :                 return (size_t)read_file(m_file_handle, out_buffer, (uint32_t)num_bytes);
     118                 :             :         }
     119                 :             : 
     120                 :         504 :         virtual size_t get_size()
     121                 :             :         {
     122                 :         504 :                 return (size_t)get_file_size(m_file_handle);
     123                 :             :         }
     124                 :             : 
     125                 :             : private:
     126                 :             :         friend class virtual_filesystem;
     127                 :             : 
     128                 :             :         FileHandleType m_file_handle;
     129                 :             : };
     130                 :             : 
     131                 :             : 
     132                 :             : 
     133                 :         230 : void virtual_filesystem::initialize(const char** include_paths, size_t num_include_paths)
     134                 :             : {
     135                 :         230 :         m_include_paths.reset();
     136                 :             : 
     137         [ +  + ]:         690 :         for (size_t i = 0; i < num_include_paths; ++i)
     138                 :             :         {
     139                 :         460 :                 m_include_paths[(int)i] = include_paths[i];
     140                 :             :         }
     141                 :             : 
     142                 :         230 :         m_last_error = vfe_none;
     143                 :         230 :         m_memory_files.reset();
     144                 :         230 : }
     145                 :             : 
     146                 :         230 : void virtual_filesystem::destroy()
     147                 :             : {
     148                 :         230 :         m_include_paths.reset();
     149                 :         230 : }
     150                 :             : 
     151                 :             : 
     152                 :         532 : virtual_file_handle virtual_filesystem::open_file(const char* path, const char* base_path)
     153                 :             : {
     154                 :         532 :         m_last_error = vfe_none;
     155                 :             : 
     156                 :         532 :         string absolutepath = create_absolute_path(base_path, path);
     157                 :             : 
     158                 :         532 :         virtual_file_type vft = get_file_type_from_path(absolutepath);
     159                 :             : 
     160         [ +  + ]:         532 :         if (vft != vft_memory_file)
     161                 :             :         {
     162                 :         532 :                 asar_throw_warning(0, warning_id_check_memory_file, path, (int)warning_id_check_memory_file);
     163                 :             :         }
     164                 :             : 
     165      [ +  -  - ]:         532 :         switch (vft)
     166                 :             :         {
     167                 :         532 :                 case vft_physical_file:
     168                 :             :                 {
     169                 :         532 :                         physical_file* new_file = new physical_file;
     170                 :             : 
     171         [ -  + ]:         266 :                         if (new_file == nullptr)
     172                 :             :                         {
     173                 :           0 :                                 m_last_error = vfe_unknown;
     174                 :           0 :                                 return INVALID_VIRTUAL_FILE_HANDLE;
     175                 :             :                         }
     176                 :             : 
     177                 :         532 :                         virtual_file_error error = new_file->open(absolutepath);
     178                 :             : 
     179         [ +  + ]:         532 :                         if (error != vfe_none)
     180                 :             :                         {
     181                 :          28 :                                 delete new_file;
     182                 :          28 :                                 m_last_error = error;
     183                 :          28 :                                 return INVALID_VIRTUAL_FILE_HANDLE;
     184                 :             :                         }
     185                 :             : 
     186                 :         252 :                         return static_cast<virtual_file_handle>(new_file);
     187                 :             :                 }
     188                 :             : 
     189                 :           0 :                 case vft_memory_file:
     190                 :             :                 {
     191   [ #  #  #  # ]:           0 :                         if(m_memory_files.exists(absolutepath)) {
     192                 :           0 :                                 memory_buffer mem_buf = m_memory_files.find(absolutepath);
     193                 :           0 :                                 memory_file* new_file = new memory_file(mem_buf.data, mem_buf.length);
     194                 :           0 :                                 return static_cast<virtual_file_handle>(new_file);
     195                 :             :                         } else {
     196                 :           0 :                                 m_last_error =  vfe_doesnt_exist;
     197                 :           0 :                                 return INVALID_VIRTUAL_FILE_HANDLE;
     198                 :             :                         }
     199                 :             :                 }
     200                 :             : 
     201                 :           0 :                 default:
     202                 :             :                         // We should not get here
     203                 :           0 :                         m_last_error = vfe_unknown;
     204                 :           0 :                         return INVALID_VIRTUAL_FILE_HANDLE;
     205                 :             :         }
     206                 :         532 : }
     207                 :             : 
     208                 :         504 : void virtual_filesystem::close_file(virtual_file_handle file_handle)
     209                 :             : {
     210         [ +  - ]:         504 :         if (file_handle != INVALID_VIRTUAL_FILE_HANDLE)
     211                 :             :         {
     212                 :         252 :                 virtual_file* file = static_cast<virtual_file*>(file_handle);
     213                 :             : 
     214                 :         504 :                 file->close();
     215                 :             : 
     216                 :         504 :                 delete file;
     217                 :             :         }
     218                 :         504 : }
     219                 :             : 
     220                 :             : 
     221                 :             : 
     222                 :         518 : size_t virtual_filesystem::read_file(virtual_file_handle file_handle, void* out_buffer, size_t pos, size_t num_bytes)
     223                 :             : {
     224         [ +  - ]:         518 :         if (file_handle != INVALID_VIRTUAL_FILE_HANDLE)
     225                 :             :         {
     226                 :         259 :                 virtual_file* file = static_cast<virtual_file*>(file_handle);
     227                 :             : 
     228                 :         518 :                 return file->read(out_buffer, pos, num_bytes);
     229                 :             :         }
     230                 :             : 
     231                 :           0 :         return 0u;
     232                 :             : }
     233                 :             : 
     234                 :         504 : size_t virtual_filesystem::get_file_size(virtual_file_handle file_handle)
     235                 :             : {
     236         [ +  - ]:         504 :         if (file_handle != INVALID_VIRTUAL_FILE_HANDLE)
     237                 :             :         {
     238                 :         252 :                 virtual_file* file = static_cast<virtual_file*>(file_handle);
     239                 :             : 
     240                 :         504 :                 return file->get_size();
     241                 :             :         }
     242                 :             : 
     243                 :           0 :         return 0u;
     244                 :             : }
     245                 :             : 
     246                 :             : 
     247                 :         532 : virtual_filesystem::virtual_file_type virtual_filesystem::get_file_type_from_path(const char* path)
     248                 :             : {
     249         [ +  + ]:         532 :         if(m_memory_files.exists(path)) {
     250                 :           0 :                 return vft_memory_file;
     251                 :             :         } else {
     252                 :         532 :                 return vft_physical_file;
     253                 :             :         }
     254                 :             : }
     255                 :             : 
     256                 :           0 : void virtual_filesystem::add_memory_file(const char* name, const void* buffer, size_t length) {
     257                 :           0 :         memory_buffer mem_buf = { buffer, length };
     258                 :           0 :         string normalized_path = normalize_path(name);
     259                 :           0 :         m_memory_files.remove(normalized_path);
     260                 :           0 :         m_memory_files.create(normalized_path) = mem_buf;
     261                 :           0 : }
     262                 :             : 
     263                 :        3745 : bool virtual_filesystem::is_path_absolute(const char* path)
     264                 :             : {
     265                 :        3745 :         return path_is_absolute(path);
     266                 :             : }
     267                 :             : 
     268                 :        5279 : string virtual_filesystem::create_absolute_path(const char* base, const char* target)
     269                 :             : {
     270   [ +  +  +  +  :        5279 :         if (is_path_absolute(target) || base == nullptr || base[0] == '\0')
          +  +  +  +  +  
                      + ]
     271                 :             :         {
     272                 :        1790 :                 return normalize_path(target);
     273                 :             :         }
     274                 :             : 
     275                 :        3489 :         string path_to_use = "";
     276                 :        3489 :         string test_path = "";
     277                 :             : 
     278                 :        3489 :         test_path = normalize_path(target);
     279                 :             : 
     280                 :             :         // First check if path is absolute
     281   [ +  -  -  + ]:        3489 :         if (path_is_absolute(test_path))
     282                 :             :         {
     283   [ #  #  #  #  :           0 :                 if (m_memory_files.exists(test_path) || file_exists(test_path))
          #  #  #  #  #  
                      # ]
     284                 :             :                 {
     285                 :           0 :                         path_to_use = test_path;
     286                 :             :                 }
     287                 :             :         }
     288                 :             :         else
     289                 :             :         {
     290                 :             :                 // Now check if path exists relative to the base path
     291         [ +  - ]:        2850 :                 if (base != nullptr)
     292                 :             :                 {
     293                 :        3489 :                         test_path = create_combined_path(dir(base), target);
     294                 :             :                 }
     295                 :             : 
     296   [ +  -  +  -  :        3489 :                 if (test_path != "" && (m_memory_files.exists(test_path) || file_exists(test_path)))
          +  -  +  +  +  
                +  +  + ]
     297                 :             :                 {
     298                 :        2834 :                         path_to_use = test_path;
     299                 :             :                 }
     300                 :             :                 else
     301                 :             :                 {
     302                 :             :                         // Finally check if path exists relative to any include path
     303                 :          16 :                         bool found = false;
     304         [ +  + ]:          90 :                         for (int i = 0; i < m_include_paths.count; ++i)
     305                 :             :                         {
     306                 :          64 :                                 test_path = create_combined_path(m_include_paths[i], target);
     307                 :             : 
     308   [ +  -  +  -  :          64 :                                 if (m_memory_files.exists(test_path) || file_exists(test_path))
          +  +  +  +  +  
                      + ]
     309                 :             :                                 {
     310                 :           3 :                                         found = true;
     311                 :           3 :                                         path_to_use = test_path;
     312                 :           3 :                                         break;
     313                 :             :                                 }
     314                 :             :                         }
     315                 :             : 
     316         [ +  + ]:          16 :                         if (!found)
     317                 :             :                         {
     318                 :             :                                 // Reset our path so that we don't return an empty one
     319                 :             :                                 // (that will do some weird shit and fuck up error messages)
     320                 :          13 :                                 path_to_use = target;
     321                 :             :                         }
     322                 :             :                 }
     323                 :             :         }
     324                 :             : 
     325                 :        3489 :         return path_to_use;
     326                 :        3489 : }
        

Generated by: LCOV version 2.0-1