/src/Fast-DDS/thirdparty/taocpp-pegtl/pegtl/internal/file_reader.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2014-2020 Dr. Colin Hirsch and Daniel Frey |
2 | | // Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/ |
3 | | |
4 | | #ifndef TAO_PEGTL_INTERNAL_FILE_READER_HPP |
5 | | #define TAO_PEGTL_INTERNAL_FILE_READER_HPP |
6 | | |
7 | | #include <cstdio> |
8 | | #include <memory> |
9 | | #include <string> |
10 | | #include <utility> |
11 | | |
12 | | #include "../config.hpp" |
13 | | #include "../input_error.hpp" |
14 | | |
15 | | namespace tao |
16 | | { |
17 | | namespace TAO_PEGTL_NAMESPACE |
18 | | { |
19 | | namespace internal |
20 | | { |
21 | | inline std::FILE* file_open( const char* filename ) |
22 | 0 | { |
23 | 0 | errno = 0; |
24 | 0 | #if defined( _MSC_VER ) |
25 | 0 | std::FILE* file; |
26 | 0 | if( ::fopen_s( &file, filename, "rb" ) == 0 ) |
27 | 0 | #elif defined( __MINGW32__ ) |
28 | 0 | if( auto* file = std::fopen( filename, "rb" ) ) // NOLINT |
29 | 0 | #else |
30 | 0 | if( auto* file = std::fopen( filename, "rbe" ) ) // NOLINT |
31 | 0 | #endif |
32 | 0 | { |
33 | 0 | return file; |
34 | 0 | } |
35 | 0 | TAO_PEGTL_THROW_INPUT_ERROR( "unable to fopen() file " << filename << " for reading" ); |
36 | 0 | } |
37 | | |
38 | | struct file_close |
39 | | { |
40 | | void operator()( FILE* f ) const noexcept |
41 | 0 | { |
42 | 0 | std::fclose( f ); // NOLINT |
43 | 0 | } |
44 | | }; |
45 | | |
46 | | class file_reader |
47 | | { |
48 | | public: |
49 | | explicit file_reader( const char* filename ) |
50 | | : m_source( filename ), |
51 | | m_file( file_open( m_source ) ) |
52 | 0 | { |
53 | 0 | } |
54 | | |
55 | | file_reader( FILE* file, const char* filename ) noexcept |
56 | | : m_source( filename ), |
57 | | m_file( file ) |
58 | 0 | { |
59 | 0 | } |
60 | | |
61 | | file_reader( const file_reader& ) = delete; |
62 | | file_reader( file_reader&& ) = delete; |
63 | | |
64 | | ~file_reader() = default; |
65 | | |
66 | | void operator=( const file_reader& ) = delete; |
67 | | void operator=( file_reader&& ) = delete; |
68 | | |
69 | | std::size_t size() const |
70 | 0 | { |
71 | 0 | errno = 0; |
72 | 0 | if( std::fseek( m_file.get(), 0, SEEK_END ) != 0 ) { |
73 | 0 | TAO_PEGTL_THROW_INPUT_ERROR( "unable to fseek() to end of file " << m_source ); // LCOV_EXCL_LINE |
74 | 0 | } |
75 | 0 | errno = 0; |
76 | 0 | const auto s = std::ftell( m_file.get() ); |
77 | 0 | if( s < 0 ) { |
78 | 0 | TAO_PEGTL_THROW_INPUT_ERROR( "unable to ftell() file size of file " << m_source ); // LCOV_EXCL_LINE |
79 | 0 | } |
80 | 0 | errno = 0; |
81 | 0 | if( std::fseek( m_file.get(), 0, SEEK_SET ) != 0 ) { |
82 | 0 | TAO_PEGTL_THROW_INPUT_ERROR( "unable to fseek() to beginning of file " << m_source ); // LCOV_EXCL_LINE |
83 | 0 | } |
84 | 0 | return std::size_t( s ); |
85 | 0 | } |
86 | | |
87 | | std::string read() const |
88 | 0 | { |
89 | 0 | std::string nrv; |
90 | 0 | nrv.resize( size() ); |
91 | 0 | errno = 0; |
92 | 0 | if( !nrv.empty() && ( std::fread( &nrv[ 0 ], nrv.size(), 1, m_file.get() ) != 1 ) ) { |
93 | 0 | TAO_PEGTL_THROW_INPUT_ERROR( "unable to fread() file " << m_source << " size " << nrv.size() ); // LCOV_EXCL_LINE |
94 | 0 | } |
95 | 0 | return nrv; |
96 | 0 | } |
97 | | |
98 | | private: |
99 | | const char* const m_source; |
100 | | const std::unique_ptr< std::FILE, file_close > m_file; |
101 | | }; |
102 | | |
103 | | } // namespace internal |
104 | | |
105 | | } // namespace TAO_PEGTL_NAMESPACE |
106 | | |
107 | | } // namespace tao |
108 | | |
109 | | #endif |