Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 39 additions & 31 deletions include/daw/daw_read_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

#pragma once

#include "ciso646.h"
#include "daw_attributes.h"
#include "daw_traits.h"
#include "daw/ciso646.h"
#include "daw/daw_attributes.h"
#include "daw/daw_string_view.h"
#include "daw/daw_traits.h"

#include <cstddef>
#include <cstdio>
Expand All @@ -19,95 +20,102 @@
#include <iostream>
#include <optional>
#include <string>
#include <string_view>
#include <utility>

namespace daw {
template<typename CharT = char>
DAW_ATTRIB_NOINLINE std::optional<std::basic_string<CharT>>
read_file( std::string const &path ) {
read_file( daw::string_view path ) {
auto ec = std::error_code{ };
auto const fsize = std::filesystem::file_size( path, ec );
auto const fsize =
std::filesystem::file_size( std::string_view( path ), ec );
if( ec ) {
return std::nullopt;
}
if( fsize == 0 ) {
return std::basic_string<CharT>{ };
if( fsize % sizeof( CharT ) != 0 ) {
return std::nullopt;
}
auto const element_count = fsize / sizeof( CharT );
if( static_cast<std::uintmax_t>( std::basic_string<CharT>{ }.max_size( ) ) <
fsize ) {
element_count ) {
// File is too big to fit into string(WIN32)
return std::nullopt;
}
auto result =
std::basic_string<CharT>( static_cast<std::size_t>( fsize ), CharT{ } );
auto result = std::basic_string<CharT>(
static_cast<std::size_t>( element_count ), CharT{ } );
#if defined( _MSC_VER )
FILE *f = nullptr;
auto err = fopen_s( &f, path.c_str( ), "rb" );
if( err ) {
auto err = fopen_s( &f, path.get_c_str( ).c_str( ), "rb" );
if( err or not f ) {
return std::nullopt;
}
#else
auto *f = fopen( path.c_str( ), "rb" );
auto *f = fopen( path.get_c_str( ).c_str( ), "rb" );
if( not f ) {
return std::nullopt;
}
#endif
auto num_read = fread( result.data( ), sizeof( CharT ), result.size( ), f );
if( num_read != ( result.size( ) / sizeof( CharT ) ) ) {
fclose( f );
auto const num_read =
fread( result.data( ), sizeof( CharT ), result.size( ), f );
auto const close_result = fclose( f );
if( num_read != result.size( ) or close_result != 0 ) {
return std::nullopt;
}
fclose( f );
return result;
}

struct terminate_on_read_file_error_t {};
inline constexpr auto terminate_on_read_file_error =
terminate_on_read_file_error_t{ };

inline std::string read_file( std::string const &path,
inline std::string read_file( daw::string_view path,
terminate_on_read_file_error_t ) {
auto result = read_file( path );
if( not result ) {
std::cerr << "Error: could not open file '" << path << "'\n";
std::terminate( );
}
return *result;
return std::move( *result );
}

#if defined( _MSC_VER )
DAW_ATTRIB_NOINLINE inline std::optional<std::wstring>
read_wfile( std::wstring path ) {
read_wfile( daw::wstring_view path ) {
using CharT = wchar_t;
auto ec = std::error_code{ };
auto const fsize = std::filesystem::file_size( path, ec );
auto const fsize =
std::filesystem::file_size( std::wstring_view( path ), ec );
if( ec ) {
return std::nullopt;
}
if( fsize == 0 ) {
return std::basic_string<CharT>{ };
if( fsize % sizeof( CharT ) != 0 ) {
return std::nullopt;
}
auto const element_count = fsize / sizeof( CharT );
if( static_cast<std::uintmax_t>( std::basic_string<CharT>{ }.max_size( ) ) <
fsize ) {
element_count ) {
// File is too big to fit into string(WIN32)
return std::nullopt;
}
auto result =
std::basic_string<CharT>( static_cast<std::size_t>( fsize ), CharT{ } );
auto result = std::basic_string<CharT>(
static_cast<std::size_t>( element_count ), CharT{ } );
FILE *f = nullptr;
auto err = _wfopen_s( &f, path.c_str( ), L"rb" );
if( err ) {
auto err = _wfopen_s( &f, path.get_c_str( ).c_str( ), L"rb" );
if( err or not f ) {
return std::nullopt;
}
auto num_read = fread( result.data( ), sizeof( CharT ), result.size( ), f );
if( num_read != ( result.size( ) / sizeof( CharT ) ) ) {
auto const num_read =
fread( result.data( ), sizeof( CharT ), result.size( ), f );
auto const close_result = fclose( f );
if( num_read != result.size( ) or close_result != 0 ) {
return std::nullopt;
}
return result;
}

DAW_ATTRIB_NOINLINE inline std::wstring
read_wfile( std::wstring const &path, terminate_on_read_file_error_t ) {
read_wfile( daw::wstring_view path, terminate_on_read_file_error_t ) {
auto result = read_wfile( path );
if( not result ) {
std::wcerr << L"Error: could not open file '" << path << L'\n';
Expand Down
Loading