istream.hppGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef ADOBE_ISTREAM_HPP
00010 #define ADOBE_ISTREAM_HPP
00011
00012 #include <adobe/config.hpp>
00013
00014 #include <ios>
00015 #include <istream>
00016 #include <stdexcept>
00017 #include <vector>
00018
00019 #include <adobe/name_fwd.hpp>
00020 #include <adobe/istream_fwd.hpp>
00021
00022 #include <boost/any.hpp>
00023 #include <boost/shared_ptr.hpp>
00024 #include <boost/function.hpp>
00025
00026
00027
00028 namespace adobe {
00029
00030
00031
00032 #if 0
00033 std::istream& getline(std::istream& is, std::string& str);
00034 #endif
00035
00036
00037
00077
00078
00079
00080
00133
00134
00135
00136
00151
00152
00153 struct line_position_t
00154 {
00155 public:
00156 typedef boost::function<std::string (name_t, std::streampos)> getline_proc_impl_t;
00157 typedef boost::shared_ptr<getline_proc_impl_t> getline_proc_t;
00158
00159
00160 line_position_t( name_t file_path,
00161 getline_proc_t getline_proc,
00162 int line_number = 1,
00163 std::streampos line_start = 0,
00164 std::streampos position = -1);
00165
00166
00167 explicit line_position_t(const char*, int line_index = 0);
00168
00169 #if !defined(ADOBE_NO_DOCUMENTATION)
00170 line_position_t();
00171 #endif // !defined(ADOBE_NO_DOCUMENTATION)
00172
00173 const char* stream_name() const
00174 { return file_name_m.c_str(); }
00175
00176 std::string file_snippet() const
00177 {
00178 return getline_proc_m ?
00179 (*getline_proc_m)(file_name_m, line_start_m) :
00180 std::string();
00181 }
00182
00183 int line_number_m;
00184 std::streampos line_start_m;
00185 std::streampos position_m;
00186
00187 #if !defined(ADOBE_NO_DOCUMENTATION)
00188 private:
00189 name_t file_name_m;
00190 getline_proc_t getline_proc_m;
00191 #endif // !defined(ADOBE_NO_DOCUMENTATION)
00192 };
00193
00194
00195
00196 std::ostream& operator<<(std::ostream&, const line_position_t&);
00197
00198
00199
00200 class stream_error_t : public std::logic_error
00201 {
00202 public:
00203 typedef std::vector<line_position_t> position_set_t;
00204
00205 stream_error_t(const std::exception& base, const line_position_t& position) :
00206 std::logic_error(base.what())
00207 {
00208 try {
00209 const stream_error_t* error = dynamic_cast<const stream_error_t*>(&base);
00210
00211 if (error) line_position_set_m = error->line_position_set_m;
00212
00213 line_position_set_m.push_back(position);
00214 } catch (...) { }
00215 }
00216
00217 stream_error_t(const char* what, const line_position_t& position) :
00218 std::logic_error(what),
00219 line_position_set_m(1, position)
00220 { }
00221
00222 stream_error_t(const std::string& what, const line_position_t& position) :
00223 std::logic_error(what),
00224 line_position_set_m(1, position)
00225 { }
00226
00227 const position_set_t& line_position_set() const
00228 { return line_position_set_m; }
00229
00230 #if !defined(ADOBE_NO_DOCUMENTATION)
00231 ~stream_error_t() throw()
00232 { }
00233
00234 private:
00235 position_set_t line_position_set_m;
00236 #endif // !defined(ADOBE_NO_DOCUMENTATION)
00237 };
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 template <typename I>
00252 bool is_line_end(I& first, I last)
00253 {
00254
00255
00256 typename std::iterator_traits<I>::value_type c(*first);
00257
00258 if (c != '\n' && c != '\r') return false;
00259
00260 ++first;
00261
00262 if (c == '\r' && first != last && *first == '\n') ++first;
00263
00264 return true;
00265 }
00266
00267
00268
00269 template <typename I>
00270 std::size_t is_line_end(I& first, I last, char c)
00271 {
00272
00273
00274 if (c == '\n') return 1;
00275
00276 if (c == '\r')
00277 {
00278 if (first != last && *first == '\n')
00279 {
00280 ++first;
00281
00282 return 2;
00283 }
00284
00285 return 1;
00286 }
00287
00288 return 0;
00289 }
00290
00291
00292
00293 template <typename I>
00294 std::pair<I, std::string> get_line(I first, I last)
00295 {
00296 std::string result;
00297
00298 while (first != last && !is_line_end(first, last))
00299 {
00300 result.append(1, *first);
00301 ++ first;
00302 }
00303
00304 return std::make_pair(first, result);
00305 }
00306
00307
00308
00309 }
00310
00311
00312
00313 #endif
00314
00315
|