libzypp 17.31.6
ContentFileReader.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12#include <iostream>
13#include <sstream>
14
15#include <zypp/base/LogTools.h>
16#include <zypp/base/String.h>
17#include <zypp/base/IOStream.h>
18#include <zypp-core/base/UserRequestException>
19#include <zypp-core/parser/ParseException>
20
23
24using std::endl;
25#undef ZYPP_BASE_LOGGER_LOGGROUP
26#define ZYPP_BASE_LOGGER_LOGGROUP "parser::susetags"
27
29namespace zypp
30{
32 namespace parser
33 {
35 namespace susetags
36 {
37
39 //
40 // CLASS NAME : ContentFileReader::Impl
41 //
44 {
45 public:
47 {}
48
50 {
51 if ( !_repoindex )
53 return *_repoindex;
54 }
55
56 bool hasRepoIndex() const
57 { return _repoindex != nullptr; }
58
59 RepoIndex_Ptr handoutRepoIndex()
60 {
61 RepoIndex_Ptr ret;
62 ret.swap( _repoindex );
63 _repoindex = nullptr;
64 return ret;
65 }
66
67 public:
68 bool setFileCheckSum( std::map<std::string, CheckSum> & map_r, const std::string & value ) const
69 {
70 bool error = false;
71 std::vector<std::string> words;
72 if ( str::split( value, std::back_inserter( words ) ) == 3 )
73 {
74 map_r[words[2]] = CheckSum( words[0], words[1] );
75 }
76 else
77 {
78 error = true;
79 }
80 return error;
81 }
82
83 public:
84 std::string _inputname;
85
86 private:
87 RepoIndex_Ptr _repoindex;
88 };
90
92 //
93 // CLASS NAME : ContentFileReader
94 //
96
98 //
99 // METHOD NAME : ContentFileReader::ContentFileReader
100 // METHOD TYPE : Ctor
101 //
103 {}
104
106 //
107 // METHOD NAME : ContentFileReader::~ContentFileReader
108 // METHOD TYPE : Dtor
109 //
111 {}
112
114 //
115 // METHOD NAME : ContentFileReader::beginParse
116 // METHOD TYPE : void
117 //
119 {
120 _pimpl.reset( new Impl() );
121 // actually mandatory, but in case they were forgotten...
122 _pimpl->repoindex().descrdir = "suse/setup/descr";
123 _pimpl->repoindex().datadir = "suse";
124 }
125
127 //
128 // METHOD NAME : ContentFileReader::endParse
129 // METHOD TYPE : void
130 //
132 {
133 // consume oldData
134 if ( _pimpl->hasRepoIndex() )
135 {
136 if ( _repoIndexConsumer )
137 _repoIndexConsumer( _pimpl->handoutRepoIndex() );
138 }
139
140 MIL << "[Content]" << endl;
141 _pimpl.reset();
142 }
143
145 //
146 // METHOD NAME : ContentFileReader::userRequestedAbort
147 // METHOD TYPE : void
148 //
150 {
151 ZYPP_THROW( AbortRequestException( errPrefix( lineNo_r ) ) );
152 }
153
155 //
156 // METHOD NAME : ContentFileReader::errPrefix
157 // METHOD TYPE : std::string
158 //
159 std::string ContentFileReader::errPrefix( unsigned lineNo_r,
160 const std::string & msg_r,
161 const std::string & line_r ) const
162 {
163 return str::form( "%s:%u:%s | %s",
164 _pimpl->_inputname.c_str(),
165 lineNo_r,
166 line_r.c_str(),
167 msg_r.c_str() );
168 }
169
171 //
172 // METHOD NAME : ContentFileReader::parse
173 // METHOD TYPE : void
174 //
176 const ProgressData::ReceiverFnc & fnc_r )
177 {
178 MIL << "Start parsing content repoindex" << input_r << endl;
179 if ( ! input_r.stream() )
180 {
181 std::ostringstream s;
182 s << "Can't read bad stream: " << input_r;
183 ZYPP_THROW( ParseException( s.str() ) );
184 }
185 beginParse();
186 _pimpl->_inputname = input_r.name();
187
188 ProgressData ticks( makeProgressData( input_r ) );
189 ticks.sendTo( fnc_r );
190 if ( ! ticks.toMin() )
192
193 iostr::EachLine line( input_r );
194 for( ; line; line.next() )
195 {
196 // strip 1st word from line to separate tag and value.
197 std::string value( *line );
198 std::string key( str::stripFirstWord( value, /*ltrim_first*/true ) );
199
200 if ( key.empty() || *key.c_str() == '#' ) // empty or comment line
201 {
202 continue;
203 }
204
205 // strip modifier if exists
206 std::string modifier;
207 std::string::size_type pos = key.rfind( '.' );
208 if ( pos != std::string::npos )
209 {
210 modifier = key.substr( pos+1 );
211 key.erase( pos );
212 }
213
214 //
215 // ReppoIndex related data:
216 //
217 else if ( key == "DESCRDIR" )
218 {
219 _pimpl->repoindex().descrdir = value;
220 }
221 else if ( key == "DATADIR" )
222 {
223 _pimpl->repoindex().datadir = value;
224 }
225 else if ( key == "KEY" )
226 {
227 if ( _pimpl->setFileCheckSum( _pimpl->repoindex().signingKeys, value ) )
228 {
229 ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [KEY algorithm checksum filename]", *line ) ) );
230 }
231 }
232 else if ( key == "META" )
233 {
234 if ( _pimpl->setFileCheckSum( _pimpl->repoindex().metaFileChecksums, value ) )
235 {
236 ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [algorithm checksum filename]", *line ) ) );
237 }
238 }
239 else if ( key == "HASH" )
240 {
241 if ( _pimpl->setFileCheckSum( _pimpl->repoindex().mediaFileChecksums, value ) )
242 {
243 ZYPP_THROW( ParseException( errPrefix( line.lineNo(), "Expected [algorithm checksum filename]", *line ) ) );
244 }
245 }
246 else
247 {
248 DBG << errPrefix( line.lineNo(), "ignored", *line ) << endl;
249 }
250
251
252 if ( ! ticks.set( input_r.stream().tellg() ) )
253 userRequestedAbort( line.lineNo() );
254 }
255
256 //
257 // post processing
258 //
259 if ( ! ticks.toMax() )
260 userRequestedAbort( line.lineNo() );
261
262 endParse();
263 MIL << "Done parsing " << input_r << endl;
264 }
265
267 } // namespace susetags
270 } // namespace parser
273} // namespace zypp
Helper to create and pass std::istream.
Definition: inputstream.h:57
const std::string & name() const
Name of the std::istream.
Definition: inputstream.h:107
std::istream & stream() const
The std::istream.
Definition: inputstream.h:93
Maintain [min,max] and counter (value) for progress counting.
Definition: progressdata.h:131
void sendTo(const ReceiverFnc &fnc_r)
Set ReceiverFnc.
Definition: progressdata.h:226
bool toMax()
Set counter value to current max value (unless no range).
Definition: progressdata.h:273
function< bool(const ProgressData &)> ReceiverFnc
Most simple version of progress reporting The percentage in most cases.
Definition: progressdata.h:139
bool toMin()
Set counter value to current min value.
Definition: progressdata.h:269
bool set(value_type val_r)
Set new counter value.
Definition: progressdata.h:246
Simple lineparser: Traverse each line in a file.
Definition: IOStream.h:112
unsigned lineNo() const
Return the current line number.
Definition: IOStream.h:126
bool next()
Advance to next line.
Definition: IOStream.cc:72
virtual void userRequestedAbort(unsigned lineNo_r)
Called when user(callback) request to abort.
virtual void parse(const InputStream &imput_r, const ProgressData::ReceiverFnc &fnc_r=ProgressData::ReceiverFnc())
Parse the stream.
virtual void endParse()
Called when the parse is done.
std::string errPrefix(unsigned lineNo_r, const std::string &msg_r=std::string(), const std::string &line_r="-") const
Prefix exception message with line information.
RW_pointer< Impl, rw_pointer::Scoped< Impl > > _pimpl
virtual void beginParse()
Called when start parsing.
Repository content data (from /content file).
Definition: RepoIndex.h:49
SolvableIdType size_type
Definition: PoolMember.h:126
std::string stripFirstWord(std::string &line, const bool ltrim_first)
Definition: String.cc:263
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
Definition: String.cc:36
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition: String.h:531
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
ProgressData makeProgressData(const InputStream &input_r)
bool setFileCheckSum(std::map< std::string, CheckSum > &map_r, const std::string &value) const
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428
#define DBG
Definition: Logger.h:95
#define MIL
Definition: Logger.h:96