Adobe Source Libraries 1.49.0
A collection of C++ libraries.
Loading...
Searching...
No Matches
istream.hpp
Go to the documentation of this file.
1/*
2 Copyright 2013 Adobe
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5*/
6/**************************************************************************************************/
7
8#ifndef ADOBE_ISTREAM_HPP
9#define ADOBE_ISTREAM_HPP
10
11#include <adobe/config.hpp>
12
13#include <functional>
14#include <iosfwd>
15#include <memory>
16#include <stdexcept>
17#include <vector>
18
19#include <adobe/istream_fwd.hpp>
20#include <adobe/name.hpp>
21
22/**************************************************************************************************/
23
24namespace adobe {
25
26/**************************************************************************************************/
27
28#if 0
29std::istream& getline(std::istream& is, std::string& str);
30#endif
31
32/**************************************************************************************************/
33
42
48
54
60
67
73
74//***************************************************************************//
75//***************************************************************************//
76//***************************************************************************//
77
84
91
102
109
117
124
125
126// line_position_t is used to remember a position on a particular line of a file.
128public:
129 typedef std::function<std::string(name_t, std::streampos)> getline_proc_impl_t;
130 typedef std::shared_ptr<getline_proc_impl_t> getline_proc_t;
131
132 // line_number starts at 1.
133 line_position_t(name_t file_path, getline_proc_t getline_proc, int line_number = 1,
134 std::streampos line_start = 0, std::streampos position = -1);
135
136 // This constructor is used with __FILE__ and __LINE__, line_number starts at 1
137 explicit line_position_t(const char*, int line_number = 1);
138
139#if !defined(ADOBE_NO_DOCUMENTATION)
141#endif // !defined(ADOBE_NO_DOCUMENTATION)
142
143 const char* stream_name() const { return file_name_m.c_str(); }
144
145 std::string file_snippet() const {
146 return getline_proc_m ? (*getline_proc_m)(file_name_m, line_start_m) : std::string();
147 }
148
149 int line_number_m; // type int to match __LINE__ token
150 std::streampos line_start_m;
151 std::streampos position_m;
152
153#if !defined(ADOBE_NO_DOCUMENTATION)
154private:
155 name_t file_name_m;
156 getline_proc_t getline_proc_m;
157#endif // !defined(ADOBE_NO_DOCUMENTATION)
158};
159
160/**************************************************************************************************/
161
162std::ostream& operator<<(std::ostream&, const line_position_t&);
163
164/**************************************************************************************************/
165
166class stream_error_t : public std::logic_error {
167public:
168 using position_set_t = std::vector<line_position_t>;
169
170 stream_error_t(const std::exception& base, const line_position_t& position)
171 : std::logic_error(base.what()) {
172 try {
173 const stream_error_t* error = dynamic_cast<const stream_error_t*>(&base);
174
175 if (error)
176 line_position_set_m = error->line_position_set_m;
177
178 line_position_set_m.push_back(position);
179 } catch (...) {
180 }
181 }
182
183 stream_error_t(const char* what, const line_position_t& position)
184 : std::logic_error(what), line_position_set_m(1, position) {}
185
186 stream_error_t(const std::string& what, const line_position_t& position)
187 : std::logic_error(what), line_position_set_m(1, position) {}
188
189 const position_set_t& line_position_set() const { return line_position_set_m; }
190
191#if !defined(ADOBE_NO_DOCUMENTATION)
193
194private:
195 position_set_t line_position_set_m;
196#endif // !defined(ADOBE_NO_DOCUMENTATION)
197};
198
199
200/**************************************************************************************************/
201
202std::ostream& operator<<(std::ostream&, const stream_error_t&);
203
204/**************************************************************************************************/
205
206/*
207 REVISIT (sparent) : I'm not certain this code is correct when used with an istream iterator
208 which might do line ending conversions with operator <<. Read up on this.
209*/
210
211/*
212 REVISIT (sparent) : The interface to is_line_end should take an iterator pair and return
213 a pair (first, bool) - not work on a reference to first.
214*/
215
216template <typename I> // I models InputIterator
217bool is_line_end(I& first, I last) {
218 // Handle any type of line ending.
219
220 typename std::iterator_traits<I>::value_type c(*first);
221
222 if (c != '\n' && c != '\r')
223 return false;
224
225 ++first;
226
227 if (c == '\r' && first != last && *first == '\n')
228 ++first;
229
230 return true;
231}
232
233/**************************************************************************************************/
234
235template <typename I> // I models InputIterator
236std::size_t is_line_end(I& first, I last, char c) {
237 // Handle any type of line ending.
238
239 if (c == '\n')
240 return 1;
241
242 if (c == '\r') {
243 if (first != last && *first == '\n') {
244 ++first;
245
246 return 2;
247 }
248
249 return 1;
250 }
251
252 return 0;
253}
254
255/**************************************************************************************************/
256
257template <typename I> // I models InputIterator
258std::pair<I, std::string> get_line(I first, I last) {
259 std::string result;
260
261 while (first != last && !is_line_end(first, last)) {
262 result.append(1, *first);
263 ++first;
264 }
265
266 return std::make_pair(first, result);
267}
268
269/**************************************************************************************************/
270
271} // namespace adobe
272
273/**************************************************************************************************/
274
275#endif
276
277/**************************************************************************************************/
An exception class thrown during parsing failures.
Definition istream.hpp:166
const position_set_t & line_position_set() const
Definition istream.hpp:189
stream_error_t(const std::exception &base, const line_position_t &position)
Definition istream.hpp:170
std::vector< line_position_t > position_set_t
Definition istream.hpp:168
stream_error_t(const std::string &what, const line_position_t &position)
Definition istream.hpp:186
stream_error_t(const char *what, const line_position_t &position)
Definition istream.hpp:183
bool is_line_end(I &first, I last)
Definition istream.hpp:217
std::pair< I, std::string > get_line(I first, I last)
Definition istream.hpp:258
std::ostream & operator<<(std::ostream &s, const extents_t &x)
STL namespace.
A type detailing parser position information.
Definition istream.hpp:127
line_position_t(name_t file_path, getline_proc_t getline_proc, int line_number=1, std::streampos line_start=0, std::streampos position=-1)
std::string file_snippet() const
Definition istream.hpp:145
const char * stream_name() const
Definition istream.hpp:143
std::streampos line_start_m
Definition istream.hpp:150
std::streampos position_m
Definition istream.hpp:151
line_position_t(const char *, int line_number=1)
std::function< std::string(name_t, std::streampos)> getline_proc_impl_t
Definition istream.hpp:129
std::shared_ptr< getline_proc_impl_t > getline_proc_t
Definition istream.hpp:130
A character string class for immutable strings.
Definition name.hpp:220