44
55#include < filesystem>
66#include < cstddef>
7+ #include < string>
8+ #include < string_view>
9+ #include < limits>
10+ #include < memory>
11+ #include < cassert>
12+ #include < vector>
13+ #include < map>
14+ #include < array>
15+ #include < span>
16+ #include < mutex>
717
818namespace hl {
919
1020class file {
1121public:
22+ class handle {
23+ public:
24+ constexpr handle () noexcept = default;
25+ handle (handle const &) noexcept = default ;
26+ handle (handle&&) noexcept = default ;
27+ handle& operator =(handle const &) noexcept = default ;
28+ handle& operator =(handle&&) noexcept = default ;
29+ [[nodiscard]] friend bool operator ==(handle const &, handle const &) noexcept = default ;
30+
31+ [[nodiscard]] explicit operator bool () const noexcept
32+ {
33+ return _id != std::numeric_limits<std::size_t >::max ();
34+ }
35+
36+ [[nodiscard]] std::size_t id () const noexcept
37+ {
38+ return _id;
39+ }
40+
41+ [[nodiscard]] file* operator ->() const ;
42+
43+ [[nodiscard]] file& operator *() const ;
44+
45+ private:
46+ std::size_t _id = std::numeric_limits<std::size_t >::max();
47+
48+ handle (std::size_t id) : _id(id) {}
49+
50+ friend class file ;
51+ };
52+
53+ class reader {
54+ public:
55+
56+ [[nodiscard]] char32_t operator [](std::size_t index) const
57+ {
58+ assert (_file != nullptr );
59+ assert (index < _lookahead.size ());
60+ return _lookahead[index];
61+ }
62+
63+ private:
64+ file* _file = nullptr ;
65+ std::size_t _position = 0 ;
66+ std::array<char32_t , 8 > _lookahead = {};
67+ };
68+
1269 /* * Create a file object with the given path.
1370 *
1471 * @param path The absolute normalized path to the file.
@@ -25,43 +82,53 @@ class file {
2582 */
2683 [[nodiscard]] std::filesystem::path const & path () const ;
2784
28- /* * The file's content.
29- *
30- * @return The content of the file as a string view.
31- */
32- [[nodiscard]] std::string_view view () const ;
85+ [[nodiscard]] std::size_t size () const noexcept
86+ {
87+ return _file_size;
88+ }
3389
34- /* * Get the line and column at the offset of the file .
90+ /* * Read the file content into a buffer .
3591 *
36- * @param offset The offset in the file.
37- * @return A pair containing the line number (0-based) and column number
38- * (0-based) .
92+ * @param position The position in the file to start reading from .
93+ * @param buffer The buffer to read the content into.
94+ * @return The number of bytes read .
3995 */
40- [[nodiscard]] std::pair<size_t , size_t > line_column (std::size_t offset) const ;
96+ [[nodiscard]] std::size_t read (std::size_t position, std::span<char > buffer) const ;
97+
98+ void close () noexcept ;
99+
100+ [[nodiscard]] static handle make_file (std::string_view path);
101+ [[nodiscard]] static handle make_file (std::string_view path, handle relative_to);
41102
42103private:
104+ inline static std::vector<std::unique_ptr<file>> _files_by_id;
105+ inline static std::map<std::string, file*> _files_by_name;
106+
43107 std::size_t _id = 0 ;
44108
45- /* * The absolute normalized path to the file.
109+ std::mutex _mutex;
110+
111+ /* * The size of the file in bytes.
112+ *
113+ * This is set when the file is read for the first time.
46114 */
47- std::filesystem::path _path ;
115+ std::size_t _file_size = 0 ;
48116
49- /* * The offset where each line starts in the file.
50- *
51- * The first element is always 0, representing the start of the file.
117+ /* * The absolute normalized path to the file.
52118 */
53- std::vector< size_t > _line_offsets ;
119+ std::filesystem::path _path ;
54120
55121 /* * Is this file a .hic source file.
56122 *
57123 * This may be false when #line directives are used to track the source of
58124 * generated code.
59125 */
60126 bool _is_source_code = false ;
127+
128+ std::ifstream _file_stream;
61129};
62130
63- [[nodiscard]] file& make_file (std::filesystem::path const & path);
64- [[nodiscard]] file& get_file (std::size_t file_id);
131+
65132
66133} // namespace hl
67134
0 commit comments