Imported Upstream version 15.21.1
[platform/upstream/libzypp.git] / zypp / base / IOStream.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/base/IOStream.cc
10  *
11 */
12 #include <iostream>
13 #include <boost/mpl/assert.hpp>
14 #include <boost/mpl/int.hpp>
15 //#include "zypp/base/Logger.h"
16
17 #include "zypp/base/IOStream.h"
18 #include "zypp/base/String.h"
19
20 using std::endl;
21 ///////////////////////////////////////////////////////////////////
22 namespace zypp
23 { /////////////////////////////////////////////////////////////////
24   ///////////////////////////////////////////////////////////////////
25   namespace iostr
26   { /////////////////////////////////////////////////////////////////
27
28     /******************************************************************
29      **
30      ** FUNCTION NAME : getline
31      ** FUNCTION TYPE : std::string
32      */
33     std::string getline( std::istream & str )
34     {
35       static const unsigned tmpBuffLen = 1024;
36       static char           tmpBuff[tmpBuffLen];
37       std::string ret;
38       do {
39         str.clear();
40         str.getline( tmpBuff, tmpBuffLen ); // always writes '\0' terminated
41         ret += tmpBuff;
42       } while( str.rdstate() == std::ios::failbit );
43
44       return ret;
45     }
46
47     ///////////////////////////////////////////////////////////////////
48     //
49     //  CLASS NAME : EachLine
50     //
51     ///////////////////////////////////////////////////////////////////
52
53     ///////////////////////////////////////////////////////////////////
54     //
55     //  METHOD NAME : EachLine::EachLine
56     //  METHOD TYPE : Ctor
57     //
58     EachLine::EachLine( std::istream & str_r, unsigned lineNo_r )
59       : _str( str_r )
60       , _lineStart( -1 )
61       , _lineNo( lineNo_r )
62       , _valid( true )
63     {
64       next();
65     }
66
67     ///////////////////////////////////////////////////////////////////
68     //
69     //  METHOD NAME : EachLine::next
70     //  METHOD TYPE : bool
71     //
72     bool EachLine::next()
73     {
74       if ( ! _valid )
75       {
76         return false;
77       }
78
79       if ( ! _str ) // usg: saw EOF in previous read
80       {
81         _line.clear();
82         return(_valid = false);
83       }
84
85       _lineStart = _str.tellg();
86       _line = iostr::getline( _str );
87       ++_lineNo;
88       if ( _str.fail() || _str.bad() )
89       {
90         _line.clear();
91         return(_valid = false);
92       }
93       return(_valid = true);
94     }
95
96     ///////////////////////////////////////////////////////////////////
97     // forEachLine
98     ///////////////////////////////////////////////////////////////////
99
100     int forEachLine( std::istream & str_r, function<bool(int, std::string)> consume_r )
101     {
102       int lineno = 0;
103       while ( str_r )
104       {
105         std::string line( getline( str_r ) );
106         if ( ! (str_r.fail() || str_r.bad()) )
107         {
108           // line contains valid data to be consumed.
109           ++lineno;
110           if ( consume_r && ! consume_r( lineno, line ) )
111           {
112             lineno = -lineno;
113             break;
114           }
115         }
116       }
117       return lineno;
118     }
119
120     // MPL checks to assert equal values for PF_?TRIM and str::?TRIM
121     BOOST_MPL_ASSERT_RELATION( int(PF_LTRIM), ==, int(str::L_TRIM) );
122     BOOST_MPL_ASSERT_RELATION( int(PF_RTRIM), ==, int(str::R_TRIM) );
123
124     int simpleParseFile( std::istream & str_r, ParseFlags flags_r, function<bool(int, std::string)> consume_r )
125     {
126       return forEachLine( str_r,
127                           [&]( int num_r, std::string line_r )->bool
128                           {
129                             if ( ! consume_r )
130                               return true;
131
132                             if ( flags_r )
133                             {
134                               if ( flags_r & PF_TRIM )
135                                 line_r = str::trim( line_r, str::Trim( unsigned(flags_r & PF_TRIM) ) );
136
137                               if ( flags_r & ~PF_TRIM )
138                               {
139                                 const char* firstNW = line_r.c_str();
140                                 while ( *firstNW == ' ' || *firstNW == '\t' )
141                                   ++firstNW;
142                                 switch ( *firstNW )
143                                 {
144                                   case '\0':    if ( flags_r & PF_SKIP_EMPTY )          return true; break;
145                                   case '#':     if ( flags_r & PF_SKIP_SHARP_COMMENT )  return true; break;
146                                 }
147                               }
148                             }
149                             return consume_r( num_r, line_r );
150                           } );
151     }
152
153     /////////////////////////////////////////////////////////////////
154   } // namespace iostr
155   ///////////////////////////////////////////////////////////////////
156   /////////////////////////////////////////////////////////////////
157 } // namespace zypp
158 ///////////////////////////////////////////////////////////////////