LCOV - code coverage report
Current view: top level - asar - virtualfile.cpp (source / functions) Coverage Total Hit
Test: asar.info Lines: 70.6 % 109 77
Test Date: 2024-01-15 16:41:12 Functions: 66.7 % 21 14
Branches: 53.0 % 66 35

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

Generated by: LCOV version 2.0-1