1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/IOStream.h
12 #ifndef ZYPP_BASE_IOSTREAM_H
13 #define ZYPP_BASE_IOSTREAM_H
16 #include <boost/io/ios_state.hpp>
18 #include "zypp/base/Flags.h"
19 #include "zypp/base/PtrTypes.h"
20 #include "zypp/base/Function.h"
21 #include "zypp/base/NonCopyable.h"
23 ///////////////////////////////////////////////////////////////////
25 { /////////////////////////////////////////////////////////////////
26 ///////////////////////////////////////////////////////////////////
27 /** Iostream related utilities.
30 { /////////////////////////////////////////////////////////////////
32 /** Save and restore streams \c width, \c precision
35 typedef boost::io::ios_base_all_saver IosFmtFlagsSaver;
38 /** Read one line from stream.
40 * Reads everything up to the next newline or EOF. newline
41 * is read but not returned.
43 * \see \ref forEachLine
45 std::string getline( std::istream & str );
47 /** Copy istream to ostream.
48 * \return reference to the ostream.
50 inline std::ostream & copy( std::istream & from_r, std::ostream & to_r )
55 while ( from_r && from_r.get( ch ) )
61 /** Copy istream to ostream, prefixing each line with \a indent_r (default <tt>"> "</tt> ).
62 * \return reference to the ostream.
64 inline std::ostream & copyIndent( std::istream & from_r, std::ostream & to_r, const std::string & indent_r = "> " )
70 while ( from_r && from_r.get( ch ) )
74 indent = ( ch == '\n' );
81 /** Copy istream to ostream, prefixing each line with \a indent_r (default <tt>"> "</tt> ).
82 * \return reference to the ostream.
84 inline void tee( std::istream & from_r, std::ostream & to1_r, std::ostream & to2_r )
86 if ( from_r && ( to1_r ||to2_r ) )
89 while ( from_r && from_r.get( ch ) )
97 ///////////////////////////////////////////////////////////////////
99 // CLASS NAME : EachLine
101 /** Simple lineparser: Traverse each line in a file.
104 * std::ifstream infile( "somefile" );
105 * for( iostr::EachLine in( infile ); in; in.next() )
107 * DBG << *in << endl;
111 class EachLine : private base::NonCopyable
114 /** Ctor taking a stream and reading the 1st line from it. */
115 EachLine( std::istream & str_r, unsigned lineNo_r = 0 );
117 /** Whether \c this contains a valid line to consume. */
121 /** Evaluate class in a boolean context. */
122 explicit operator bool() const
125 /** Return the current line number. */
126 unsigned lineNo() const
129 std::streamoff lineStart() const
130 { return _lineStart; };
132 /** Set current line number. */
133 void setLineNo( unsigned lineNo_r )
134 { _lineNo = lineNo_r; }
136 /** Access the current line. */
137 const std::string & operator*() const
139 /** \overload non const access */
140 std::string & operator*()
143 /** Access the current line. */
144 const std::string * operator->() const
147 /** Advance to next line. */
150 /** Advance \a num_r lines. */
151 bool next( unsigned num_r )
153 while ( num_r-- && next() )
161 std::streamoff _lineStart;
165 ///////////////////////////////////////////////////////////////////
167 /** Simple lineparser: Call functor \a consume_r for each line.
169 * \param str_r istream to read from.
170 * \param consume_r callback function taking linenumber and content
172 * The loop is aborted if the callback returns \c false.
175 * iostr::forEachLine( InputStream( "/my/file/to/read.txt" ),
176 * []( int num_r, std::string line_r )->bool
178 * MIL << " [" num_r << "]'" << line_r << "'" << endl;
183 * \return Number if lines consumed (negative if aborted by callback).
185 int forEachLine( std::istream & str_r, function<bool(int, std::string)> consume_r );
187 /** \ref simpleParseFile modifications before consuming a line. */
190 PF_LTRIM = 1 << 0, //< left trim whitespace
191 PF_RTRIM = 1 << 1, //< right trim whitespace
192 PF_TRIM = PF_LTRIM | PF_RTRIM, //< trim whitespace
193 PF_SKIP_EMPTY = 1 << 2, //< skip lines containing whitespace only
194 PF_SKIP_SHARP_COMMENT = 1 << 3 //< skip lines beginning with '#'
196 ZYPP_DECLARE_FLAGS( ParseFlags, ParseFlag );
197 ZYPP_DECLARE_OPERATORS_FOR_FLAGS( ParseFlags );
199 /** Simple lineparser optionally trimming and skipping comments. */
200 int simpleParseFile( std::istream & str_r, ParseFlags flags_r, function<bool(int, std::string)> consume_r );
202 /** \overload trimming lines, skipping '#'-comments and empty lines. */
203 inline int simpleParseFile( std::istream & str_r, function<bool(int, std::string)> consume_r )
204 { return simpleParseFile( str_r, PF_TRIM | PF_SKIP_EMPTY | PF_SKIP_SHARP_COMMENT , consume_r ); }
206 /////////////////////////////////////////////////////////////////
208 ///////////////////////////////////////////////////////////////////
209 /////////////////////////////////////////////////////////////////
211 ///////////////////////////////////////////////////////////////////
212 #endif // ZYPP_BASE_IOSTREAM_H