2017-01-28 04:49:09 +08:00
# include "pch.h"
2016-09-19 11:50:08 +08:00
# include "vcpkg_Files.h"
2016-12-01 06:08:43 +08:00
# include "vcpkg_System.h"
2017-04-19 05:49:50 +08:00
# include <thread>
2016-09-19 11:50:08 +08:00
2017-01-06 04:47:08 +08:00
namespace vcpkg : : Files
2016-09-19 11:50:08 +08:00
{
2016-09-24 08:57:18 +08:00
static const std : : regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std : : regex ( R " ([ \ /:*? " < > | ] ) " );
2017-04-13 14:32:29 +08:00
struct RealFilesystem final : Filesystem
2016-09-19 11:50:08 +08:00
{
2017-04-09 11:19:35 +08:00
virtual Expected < std : : string > read_contents ( const fs : : path & file_path ) const override
2016-09-19 11:50:08 +08:00
{
2017-04-09 07:26:26 +08:00
std : : fstream file_stream ( file_path , std : : ios_base : : in | std : : ios_base : : binary ) ;
if ( file_stream . fail ( ) )
{
return std : : errc : : no_such_file_or_directory ;
}
file_stream . seekg ( 0 , file_stream . end ) ;
auto length = file_stream . tellg ( ) ;
file_stream . seekg ( 0 , file_stream . beg ) ;
if ( length > SIZE_MAX )
{
return std : : errc : : file_too_large ;
}
std : : string output ;
output . resize ( static_cast < size_t > ( length ) ) ;
file_stream . read ( & output [ 0 ] , length ) ;
file_stream . close ( ) ;
return std : : move ( output ) ;
2016-09-19 11:50:08 +08:00
}
2017-04-13 14:00:42 +08:00
virtual Expected < std : : vector < std : : string > > read_lines ( const fs : : path & file_path ) const override
2017-04-09 11:19:35 +08:00
{
std : : fstream file_stream ( file_path , std : : ios_base : : in | std : : ios_base : : binary ) ;
if ( file_stream . fail ( ) )
{
return std : : errc : : no_such_file_or_directory ;
}
2016-09-19 11:50:08 +08:00
2017-04-09 11:19:35 +08:00
std : : vector < std : : string > output ;
std : : string line ;
while ( std : : getline ( file_stream , line ) )
{
output . push_back ( line ) ;
}
file_stream . close ( ) ;
2016-09-22 12:43:59 +08:00
2017-04-09 11:19:35 +08:00
return std : : move ( output ) ;
}
virtual fs : : path find_file_recursively_up ( const fs : : path & starting_dir , const std : : string & filename ) const override
2016-12-16 10:19:22 +08:00
{
2017-04-09 11:19:35 +08:00
fs : : path current_dir = starting_dir ;
for ( ; ! current_dir . empty ( ) ; current_dir = current_dir . parent_path ( ) )
{
const fs : : path candidate = current_dir / filename ;
2017-04-12 06:16:39 +08:00
if ( exists ( candidate ) )
2017-04-09 11:19:35 +08:00
{
break ;
}
}
return current_dir ;
2016-12-16 10:19:22 +08:00
}
2017-04-13 14:15:02 +08:00
virtual std : : vector < fs : : path > get_files_recursive ( const fs : : path & dir ) const override
2016-12-16 10:19:22 +08:00
{
2017-04-09 11:19:35 +08:00
std : : vector < fs : : path > ret ;
2016-12-16 10:19:22 +08:00
2017-04-12 06:16:39 +08:00
fs : : stdfs : : recursive_directory_iterator b ( dir ) , e { } ;
2017-04-09 11:19:35 +08:00
for ( ; b ! = e ; + + b )
{
ret . push_back ( b - > path ( ) ) ;
}
2016-12-16 10:19:22 +08:00
2017-04-09 11:19:35 +08:00
return ret ;
}
2017-04-13 14:32:29 +08:00
2017-04-13 14:15:02 +08:00
virtual std : : vector < fs : : path > get_files_non_recursive ( const fs : : path & dir ) const override
2016-12-16 10:19:22 +08:00
{
2017-04-09 11:19:35 +08:00
std : : vector < fs : : path > ret ;
2017-04-12 06:16:39 +08:00
fs : : stdfs : : directory_iterator b ( dir ) , e { } ;
2017-04-09 11:19:35 +08:00
for ( ; b ! = e ; + + b )
{
ret . push_back ( b - > path ( ) ) ;
}
return ret ;
2016-12-16 10:19:22 +08:00
}
2017-04-13 14:16:04 +08:00
virtual void write_lines ( const fs : : path & file_path , const std : : vector < std : : string > & lines ) override
2016-09-22 12:43:59 +08:00
{
2017-04-09 11:19:35 +08:00
std : : fstream output ( file_path , std : : ios_base : : out | std : : ios_base : : binary | std : : ios_base : : trunc ) ;
for ( const std : : string & line : lines )
2016-09-22 12:43:59 +08:00
{
2017-04-09 11:19:35 +08:00
output < < line < < " \n " ;
2016-09-22 12:43:59 +08:00
}
2017-04-09 11:19:35 +08:00
output . close ( ) ;
2016-09-22 12:43:59 +08:00
}
2017-04-09 11:19:35 +08:00
virtual void rename ( const fs : : path & oldpath , const fs : : path & newpath ) override
{
2017-04-12 06:16:39 +08:00
fs : : stdfs : : rename ( oldpath , newpath ) ;
2017-04-09 11:19:35 +08:00
}
2017-04-12 06:16:39 +08:00
virtual bool remove ( const fs : : path & path ) override
2017-04-09 11:19:35 +08:00
{
2017-04-12 06:16:39 +08:00
return fs : : stdfs : : remove ( path ) ;
}
virtual bool remove ( const fs : : path & path , std : : error_code & ec ) override
{
return fs : : stdfs : : remove ( path , ec ) ;
}
virtual std : : uintmax_t remove_all ( const fs : : path & path , std : : error_code & ec ) override
{
2017-04-19 05:49:50 +08:00
// Working around the currently buggy remove_all()
std : : uintmax_t out = fs : : stdfs : : remove_all ( path , ec ) ;
for ( int i = 0 ; i < 5 & & this - > exists ( path ) ; i + + )
{
using namespace std : : chrono_literals ;
std : : this_thread : : sleep_for ( i * 100 ms ) ;
out + = fs : : stdfs : : remove_all ( path , ec ) ;
}
if ( this - > exists ( path ) )
{
System : : println ( System : : Color : : warning , " Some files in %s were unable to be removed. Close any editors operating in this directory and retry. " , path . string ( ) ) ;
}
return out ;
2017-04-09 11:19:35 +08:00
}
virtual bool exists ( const fs : : path & path ) const override
{
2017-04-12 06:16:39 +08:00
return fs : : stdfs : : exists ( path ) ;
2017-04-09 11:19:35 +08:00
}
virtual bool is_directory ( const fs : : path & path ) const override
{
2017-04-12 06:16:39 +08:00
return fs : : stdfs : : is_directory ( path ) ;
2017-04-09 11:19:35 +08:00
}
virtual bool is_regular_file ( const fs : : path & path ) const override
{
2017-04-12 06:16:39 +08:00
return fs : : stdfs : : is_regular_file ( path ) ;
2017-04-09 11:19:35 +08:00
}
virtual bool is_empty ( const fs : : path & path ) const override
{
2017-04-12 06:16:39 +08:00
return fs : : stdfs : : is_empty ( path ) ;
2017-04-09 11:19:35 +08:00
}
virtual bool create_directory ( const fs : : path & path , std : : error_code & ec ) override
{
2017-04-12 06:16:39 +08:00
return fs : : stdfs : : create_directory ( path , ec ) ;
2017-04-09 11:19:35 +08:00
}
2017-04-18 08:44:15 +08:00
virtual bool create_directories ( const fs : : path & path , std : : error_code & ec ) override
{
return fs : : stdfs : : create_directories ( path , ec ) ;
}
2017-04-09 11:19:35 +08:00
virtual void copy ( const fs : : path & oldpath , const fs : : path & newpath , fs : : copy_options opts ) override
{
2017-04-12 06:16:39 +08:00
fs : : stdfs : : copy ( oldpath , newpath , opts ) ;
2017-04-09 11:19:35 +08:00
}
2017-04-12 06:16:39 +08:00
virtual bool copy_file ( const fs : : path & oldpath , const fs : : path & newpath , fs : : copy_options opts , std : : error_code & ec ) override
{
return fs : : stdfs : : copy_file ( oldpath , newpath , opts , ec ) ;
}
virtual fs : : file_status status ( const fs : : path & path , std : : error_code & ec ) const override
2017-04-09 11:19:35 +08:00
{
2017-04-12 06:16:39 +08:00
return fs : : stdfs : : status ( path , ec ) ;
2017-04-09 11:19:35 +08:00
}
2017-04-13 13:48:52 +08:00
virtual void write_contents ( const fs : : path & file_path , const std : : string & data ) override
{
FILE * f = nullptr ;
auto ec = _wfopen_s ( & f , file_path . native ( ) . c_str ( ) , L " wb " ) ;
Checks : : check_exit ( VCPKG_LINE_INFO , ec = = 0 ) ;
auto count = fwrite ( data . data ( ) , sizeof ( data [ 0 ] ) , data . size ( ) , f ) ;
fclose ( f ) ;
Checks : : check_exit ( VCPKG_LINE_INFO , count = = data . size ( ) ) ;
}
2017-04-18 08:44:15 +08:00
2017-04-09 11:19:35 +08:00
} ;
2016-11-30 10:08:00 +08:00
2017-04-09 11:19:35 +08:00
Filesystem & get_real_filesystem ( )
2016-11-30 10:08:00 +08:00
{
2017-04-09 11:19:35 +08:00
static RealFilesystem real_fs ;
return real_fs ;
2016-11-30 10:08:00 +08:00
}
2017-04-09 11:19:35 +08:00
bool has_invalid_chars_for_filesystem ( const std : : string & s )
2016-11-30 10:08:00 +08:00
{
2017-04-09 11:19:35 +08:00
return std : : regex_search ( s , FILESYSTEM_INVALID_CHARACTERS_REGEX ) ;
2016-11-30 10:08:00 +08:00
}
2016-12-01 06:08:43 +08:00
void print_paths ( const std : : vector < fs : : path > & paths )
{
System : : println ( " " ) ;
for ( const fs : : path & p : paths )
{
System : : println ( " %s " , p . generic_string ( ) ) ;
}
System : : println ( " " ) ;
}
2017-01-06 04:47:08 +08:00
}