]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | // |
2 | // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | // Official repository: https://github.com/boostorg/json | |
8 | // | |
9 | ||
10 | #ifndef BOOST_JSON_EXAMPLE_FILE_HPP | |
11 | #define BOOST_JSON_EXAMPLE_FILE_HPP | |
12 | ||
13 | #include <boost/json/detail/config.hpp> | |
14 | #include <cstdio> | |
15 | #include <string> | |
16 | ||
17 | class file | |
18 | { | |
19 | FILE* f_ = nullptr; | |
20 | long size_ = 0; | |
21 | ||
22 | void | |
23 | fail(boost::json::error_code& ec) | |
24 | { | |
25 | ec.assign( errno, boost::json::generic_category() ); | |
26 | } | |
27 | ||
28 | public: | |
29 | ~file() | |
30 | { | |
31 | if(f_) | |
32 | std::fclose(f_); | |
33 | } | |
34 | ||
35 | file() = default; | |
36 | ||
37 | file( file&& other ) noexcept | |
38 | : f_(other.f_) | |
39 | { | |
40 | other.f_ = nullptr; | |
41 | } | |
42 | ||
43 | file( char const* path, char const* mode ) | |
44 | { | |
45 | open( path, mode ); | |
46 | } | |
47 | ||
48 | file& | |
49 | operator=(file&& other) noexcept | |
50 | { | |
51 | close(); | |
52 | f_ = other.f_; | |
53 | other.f_ = nullptr; | |
54 | return *this; | |
55 | } | |
56 | ||
57 | void | |
58 | close() | |
59 | { | |
60 | if(f_) | |
61 | { | |
62 | std::fclose(f_); | |
63 | f_ = nullptr; | |
64 | size_ = 0; | |
65 | } | |
66 | } | |
67 | ||
68 | void | |
69 | open( | |
70 | char const* path, | |
71 | char const* mode, | |
72 | boost::json::error_code& ec) | |
73 | { | |
74 | close(); | |
1e59de90 TL |
75 | #if defined(_MSC_VER) |
76 | # pragma warning( push ) | |
77 | # pragma warning( disable : 4996 ) | |
78 | #endif | |
20effc67 | 79 | f_ = std::fopen( path, mode ); |
1e59de90 TL |
80 | #if defined(_MSC_VER) |
81 | # pragma warning( pop ) | |
82 | #endif | |
20effc67 TL |
83 | if( ! f_ ) |
84 | return fail(ec); | |
85 | if( std::fseek( f_, 0, SEEK_END ) != 0) | |
86 | return fail(ec); | |
87 | size_ = std::ftell( f_ ); | |
88 | if( size_ == -1 ) | |
89 | { | |
90 | size_ = 0; | |
91 | return fail(ec); | |
92 | } | |
93 | if( std::fseek( f_, 0, SEEK_SET ) != 0) | |
94 | return fail(ec); | |
95 | } | |
96 | ||
97 | void | |
98 | open( | |
99 | char const* path, | |
100 | char const* mode) | |
101 | { | |
102 | boost::json::error_code ec; | |
103 | open(path, mode, ec); | |
104 | if(ec) | |
105 | throw boost::json::system_error(ec); | |
106 | } | |
107 | ||
108 | long | |
109 | size() const noexcept | |
110 | { | |
111 | return size_; | |
112 | } | |
113 | ||
114 | bool | |
115 | eof() const noexcept | |
116 | { | |
117 | return std::feof( f_ ) != 0; | |
118 | } | |
119 | ||
120 | std::size_t | |
121 | read( char* data, std::size_t size, boost::json::error_code& ec) | |
122 | { | |
123 | auto const nread = std::fread( data, 1, size, f_ ); | |
124 | if( std::ferror(f_) ) | |
125 | ec.assign( errno, boost::json::generic_category() ); | |
126 | return nread; | |
127 | } | |
128 | ||
129 | std::size_t | |
130 | read( char* data, std::size_t size ) | |
131 | { | |
132 | boost::json::error_code ec; | |
133 | auto const nread = read( data, size, ec ); | |
134 | if(ec) | |
135 | throw boost::json::system_error(ec); | |
136 | return nread; | |
137 | } | |
138 | }; | |
139 | ||
140 | inline | |
141 | std::string | |
142 | read_file( char const* path, boost::json::error_code& ec ) | |
143 | { | |
144 | file f; | |
145 | f.open( path, "r", ec ); | |
146 | if(ec) | |
147 | return {}; | |
148 | std::string s; | |
149 | s.resize( f.size() ); | |
150 | s.resize( f.read( &s[0], s.size(), ec) ); | |
151 | if(ec) | |
152 | return {}; | |
153 | return s; | |
154 | } | |
155 | ||
156 | inline | |
157 | std::string | |
158 | read_file( char const* path ) | |
159 | { | |
160 | boost::json::error_code ec; | |
161 | auto s = read_file( path, ec); | |
162 | if(ec) | |
163 | throw boost::json::system_error(ec); | |
164 | return s; | |
165 | } | |
166 | ||
167 | #endif |