libzypp 17.36.7

metalinkparser.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12
13#include "metalinkparser.h"
14#include <zypp-core/base/Logger.h>
15#include <zypp-core/ByteArray.h>
16#include <zypp-core/AutoDispose.h>
17
18#include <stack>
19#include <vector>
20#include <algorithm>
21
22#include <libxml2/libxml/SAX2.h>
23
24 using namespace zypp::base;
25
26 namespace zypp::env
27{
29 inline bool ZYPP_METALINK_DEBUG()
30 {
31 static bool val = [](){
32 const char * env = getenv("ZYPP_METALINK_DEBUG");
33 return( env && zypp::str::strToBool( env, true ) );
34 }();
35 return val;
36 }
37}
38
39 namespace zypp::media {
40 enum ParserState {
41 STATE_START,
42 STATE_METALINK,
43 STATE_FILES,
44 STATE_FILE,
45 STATE_M4FILE,
46 STATE_SIZE,
47 STATE_M4SIZE,
48 STATE_VERIFICATION,
49 STATE_HASH,
50 STATE_M4HASH,
51 STATE_PIECES,
52 STATE_M4PIECES,
53 STATE_PHASH,
54 STATE_M4PHASH,
55 STATE_RESOURCES,
56 STATE_URL,
57 STATE_M4URL,
58 NUMSTATES
59 };
60
61 struct transition {
62 std::string elementName; //< Name of the element for the transition to trigger
63 ParserState transitionTo; //< The state we go into when the element name in \a elementName is encountered
64 int docontent; //< Store the content of the element in the \a content member
65 };
66
72 const std::unordered_map<ParserState, std::vector<transition> > & transitions () {
73 static std::unordered_map<ParserState, std::vector<transition> > map {
74 { STATE_START, {
75 { "metalink", STATE_METALINK, 0},
76 }
77 },
78 { STATE_METALINK, {
79 { "files", STATE_FILES, 0 },
80 { "file", STATE_M4FILE, 0 },
81 }
82 },
83 { STATE_FILES, {
84 { "file", STATE_FILE, 0},
85 }
86 },
87 { STATE_FILE, {
88 { "size", STATE_SIZE, 1 },
89 { "verification", STATE_VERIFICATION, 0 },
90 { "resources", STATE_RESOURCES, 0 },
91 }
92 },
93 { STATE_VERIFICATION, {
94 { "hash", STATE_HASH, 1 },
95 { "pieces", STATE_PIECES, 0 },
96 }
97 },
98 { STATE_PIECES, {
99 { "hash", STATE_PHASH, 1 },
100 }
101 },
102 { STATE_RESOURCES, {
103 { "url", STATE_URL, 1 },
104 }
105 },
106 { STATE_M4FILE, {
107 { "size", STATE_M4SIZE, 1 },
108 { "hash", STATE_M4HASH, 1},
109 { "url", STATE_M4URL, 1},
110 { "pieces", STATE_M4PIECES, 0},
111 }
112 },
113 { STATE_M4PIECES, {
114 { "hash", STATE_M4PHASH, 1 },
115 }
116 },
117 };
118
119 return map;
120 }
121
122 static void XMLCALL startElement(void *userData, const xmlChar *name, const xmlChar **atts);
123 static void XMLCALL endElement(void *userData, const xmlChar *name);
124 static void XMLCALL characterData(void *userData, const xmlChar *s, int len);
125
126 struct ml_parsedata : private zypp::base::NonCopyable {
127 ml_parsedata()
128 : parser( nullptr )
129 , state( STATE_START )
130 , depth( 0 )
131 , statedepth( 0 )
132 , docontent( 0 )
133 , gotfile( 0 )
134 , size( -1 )
135 , blksize( 0 )
136 , piecel( 0 )
137 , chksuml( 0 )
138 {
139 content.reserve( 256 );
140
141 xmlSAXHandler sax;
142 memset(&sax, 0, sizeof(sax));
143 sax.startElement = startElement;
144 sax.endElement = endElement;
145 sax.characters = characterData;
146
147 //internally creates a copy of xmlSaxHandler, so having it as local variable is save
148 parser = AutoDispose<xmlParserCtxtPtr>( xmlCreatePushParserCtxt(&sax, this, NULL, 0, NULL), xmlFreeParserCtxt );
149 }
150
151 void doTransition ( const transition &t ) {
152 parentStates.push( state );
153 state = t.transitionTo;
154 docontent = t.docontent;
155 statedepth = depth;
156 content.clear();
157 }
158
159 void popState () {
160 state = parentStates.top();
161 statedepth--;
162 parentStates.pop();
163
164 }
165
166 AutoDispose<xmlParserCtxtPtr> parser;
167
168 ParserState state; //< current state as defined in \ref stateswitch
169 std::stack<ParserState> parentStates;
170
171 int depth; //< current element depth of traversing the document elements
172
178 int statedepth;
179
180 std::string content; //< content of the current element
181 int docontent; //< should the content of the current elem be parsed
182
183 int gotfile;
184 off_t size;
185 std::vector<MetalinkMirror> urls;
186 size_t blksize;
187
188 std::vector<UByteArray> piece;
189 int piecel;
190
191 std::vector<UByteArray> sha1;
192 std::vector<UByteArray> zsync;
193
194 UByteArray chksum;
195 int chksuml;
196};
197
202 static const char *
203 find_attr(const char *txt, const xmlChar **atts)
204{
205 if(!atts) {
206 return nullptr;
207 }
208
209 for (; *atts; atts += 2)
210 {
211 if (!strcmp(reinterpret_cast<const char*>(*atts), txt))
212 return reinterpret_cast<const char*>(atts[1]);
213 }
214 return nullptr;
215}
216
217 static void XMLCALL
218 startElement(void *userData, const xmlChar *name, const xmlChar **atts)
219{
220 struct ml_parsedata *pd = reinterpret_cast<struct ml_parsedata *>(userData);
221
222 // if the current element depth does not match the expected depth for the current state we
223 // ignore the element and just increase the depth
224 if (pd->depth != pd->statedepth) {
225 pd->depth++;
226 return;
227 }
228 pd->depth++;
229
230 const auto &trMap = transitions();
231 const auto currStateTrs = trMap.find( pd->state );
232 if ( currStateTrs == trMap.end() )
233 return;
234
235 // check if the current element name is part of our transitions
236 auto foundTr = std::find_if( currStateTrs->second.begin(), currStateTrs->second.end(), [name]( const auto &tr ){
237 return tr.elementName == reinterpret_cast<const char *>(name);
238 });
239
240 if ( foundTr == currStateTrs->second.end() ) {
241 // we found no possible transition, ignore
242 return;
243 }
244
245 if ( ( foundTr->transitionTo == STATE_FILE || foundTr->transitionTo == STATE_M4FILE ) && pd->gotfile++)
246 return; /* ignore all but the first file */
247
248 // advance the state machine and prepare variables for the new state
249 pd->doTransition( *foundTr );
250
251 switch(pd->state)
252 {
253 case STATE_URL:
254 case STATE_M4URL:
255 {
256 const char *priority = find_attr("priority", atts);
257 const char *preference = find_attr("preference", atts);
258 const char *maxconnections = find_attr("maxconnections", atts);
259 int prio = 0;
260 auto &mirr = pd->urls.emplace_back();
261 if (priority)
262 prio = str::strtonum<int>(priority);
263 else if (preference)
264 prio = 101 - str::strtonum<int>(preference);
265 else
266 prio = 999999;
267 mirr.priority = prio;
268
269 if ( maxconnections )
270 mirr.maxConnections = str::strtonum<int>( maxconnections );
271
272 break;
273 }
274 case STATE_PIECES:
275 case STATE_M4PIECES:
276 {
277 const char *type = find_attr("type", atts);
278 const char *length = find_attr("length", atts);
279 size_t blksize = 0;
280
281 if (!type || !length)
282 {
283 pd->popState();
284 break;
285 }
286 blksize = str::strtonum<unsigned long>(length);
287 if (!blksize || (pd->blksize && pd->blksize != blksize))
288 {
289 pd->popState();
290 break;
291 }
292 pd->blksize = blksize;
293 pd->piece.clear();
294 if (!strcmp(type, "sha1") || !strcmp(type, "sha-1"))
295 pd->piecel = 20;
296 else if (!strcmp(type, "zsync"))
297 pd->piecel = 4;
298 else
299 {
300 pd->popState();
301 break;
302 }
303 break;
304 }
305 case STATE_HASH:
306 case STATE_M4HASH:
307 {
308 const char *type = find_attr("type", atts);
309 if (!type)
310 type = "?";
311 if ((!strcmp(type, "sha1") || !strcmp(type, "sha-1")) && pd->chksuml < 20)
312 pd->chksuml = 20;
313 else if (!strcmp(type, "sha256") || !strcmp(type, "sha-256"))
314 pd->chksuml = 32;
315 else
316 {
317 pd->popState();
318 pd->docontent = 0;
319 }
320 break;
321 }
322 case STATE_PHASH:
323 case STATE_M4PHASH:
324 {
325 const char *piece = find_attr("piece", atts);
326 if ( pd->state == STATE_PHASH && (!piece || str::strtonum<uint>(piece) != pd->piece.size()) )
327 {
328 pd->popState();
329 }
330 break;
331 }
332 default:
333 break;
334 }
335}
336
337 UByteArray hexstr2bytes( const std::string& str )
338{
339 return Digest::hexStringToUByteArray( str );
340}
341
342 static void XMLCALL
343 endElement(void *userData, const xmlChar *)
344{
345 struct ml_parsedata *pd = reinterpret_cast<struct ml_parsedata *>(userData);
346 //printf("end depth %d-%d name %s\n", pd->depth, pd->statedepth, name);
347 if (pd->depth != pd->statedepth)
348 {
349 pd->depth--;
350 return;
351 }
352 switch (pd->state)
353 {
354 case STATE_SIZE:
355 case STATE_M4SIZE:
356 pd->size = (off_t)str::strtonum<off_t>(pd->content); //strtoull(pd->content, 0, 10);
357 break;
358 case STATE_HASH:
359 case STATE_M4HASH:
360 pd->chksum.clear();
361 pd->chksum = hexstr2bytes( pd->content );
362 if ( pd->content.length() != size_t(pd->chksuml) * 2 || !pd->chksum.size() )
363 {
364 pd->chksum.clear();
365 pd->chksuml = 0;
366 }
367 break;
368 case STATE_PHASH:
369 case STATE_M4PHASH: {
370 if ( pd->content.length() != size_t(pd->piecel) * 2 )
371 break;
372 UByteArray pieceHash = hexstr2bytes( pd->content );
373 if ( !pieceHash.size() )
374 pieceHash.resize( pd->piecel, 0 );
375 pd->piece.push_back( pieceHash );
376 break;
377 }
378 case STATE_PIECES:
379 case STATE_M4PIECES:
380 if (pd->piecel == 4)
381 pd->zsync = pd->piece;
382 else
383 pd->sha1 = pd->piece;
384
385 pd->piecel = 0;
386 pd->piece.clear();
387 break;
388 case STATE_URL:
389 case STATE_M4URL:
390 if ( pd->content.length() )
391 pd->urls.back().url = std::string(pd->content);
392 else
393 // without a actual URL the mirror is useless
394 pd->urls.pop_back();
395 break;
396 default:
397 break;
398 }
399
400 pd->depth--;
401 pd->popState();
402 pd->docontent = 0;
403}
404
405 static void XMLCALL
406 characterData(void *userData, const xmlChar *s, int len)
407{
408 struct ml_parsedata *pd = reinterpret_cast<struct ml_parsedata *>(userData);
409 if (!pd->docontent)
410 return;
411
412 if ( pd->content.length() + len + 1 > pd->content.capacity() )
413 pd->content.reserve( pd->content.capacity() + 256 );
414 pd->content.append( s, s+len );
415}
416
417
418 MetaLinkParser::MetaLinkParser()
419 : pd( new ml_parsedata )
420{}
421
422 MetaLinkParser::~MetaLinkParser()
423{
424 delete pd;
425}
426
427 void
428 MetaLinkParser::parse(const Pathname &filename)
429{
430 parse(InputStream(filename));
431}
432
433 void
434 MetaLinkParser::parse(const InputStream &is)
435{
436 char buf[4096];
437 if (!is.stream())
438 ZYPP_THROW(Exception("MetaLinkParser: no such file"));
439 while (is.stream().good())
440 {
441 is.stream().read(buf, sizeof(buf));
442 parseBytes(buf, is.stream().gcount());
443 }
444 parseEnd();
445 MIL << "Parsed " << pd->urls.size() << " mirrors from " << is.path() << std::endl;
446 if ( env::ZYPP_METALINK_DEBUG() ) {
447 for ( const auto &mirr : pd->urls )
448 DBG << "- " << mirr.priority << " " << mirr.url << std::endl;
449 }
450}
451
452 void
453 MetaLinkParser::parseBytes(const char *buf, size_t len)
454{
455 if (!len)
456 return;
457
458 if (xmlParseChunk(pd->parser, buf, len, 0)) {
459 ZYPP_THROW(Exception("Parse Error"));
460 }
461}
462
463 void
464 MetaLinkParser::parseEnd()
465{
466 if (xmlParseChunk(pd->parser, NULL, 0, 1)) {
467 ZYPP_THROW(Exception("Parse Error"));
468 }
469 if (pd->urls.size() ) {
470 stable_sort(pd->urls.begin(), pd->urls.end(), []( const auto &a, const auto &b ){
471 return a.priority < b.priority;
472 });
473 }
474}
475
476std::vector<Url>
477 MetaLinkParser::getUrls() const
478{
479 std::vector<Url> urls;
480 urls.reserve(pd->urls.size());
481 for ( const auto &mirr : pd->urls )
482 urls.push_back( mirr.url );
483 return urls;
484}
485
486 const std::vector<MetalinkMirror> &MetaLinkParser::getMirrors() const
487{
488 return pd->urls;
489}
490
491 MediaBlockList MetaLinkParser::getBlockList() const
492{
493 MediaBlockList bl(pd->size);
494 if (pd->chksuml == 20)
495 bl.setFileChecksum("SHA1", pd->chksuml, pd->chksum.data() );
496 else if (pd->chksuml == 32)
497 bl.setFileChecksum("SHA256", pd->chksuml, pd->chksum.data());
498 if (pd->size != off_t(-1) && pd->blksize)
499 {
500 size_t nb = (pd->size + pd->blksize - 1) / pd->blksize;
501 off_t off = 0;
502 size_t size = pd->blksize;
503 for ( size_t i = 0; i < nb; i++ )
504 {
505 if (i == nb - 1)
506 {
507 size = pd->size % pd->blksize;
508 if (!size)
509 size = pd->blksize;
510 }
511 size_t blkno = bl.addBlock(off, size);
512 if ( i < pd->sha1.size())
513 {
514 bl.setChecksum(blkno, "SHA1", 20, pd->sha1[i].data());
515 if ( i < pd->zsync.size())
516 {
517 unsigned char *p = pd->zsync[i].data();
518 bl.setRsum(blkno, 4, p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24, pd->blksize);
519 }
520 }
521 off += pd->blksize;
522 }
523 }
524 return bl;
525}
526
527 const std::vector<UByteArray> &MetaLinkParser::getZsyncBlockHashes() const
528{
529 return pd->zsync;
530}
531
532 const std::vector<UByteArray> &MetaLinkParser::getSHA1BlockHashes() const
533{
534 return pd->sha1;
535}
536
537} // namespace zypp::media
zypp::AutoDispose
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
zypp::Exception
Base class for Exception.
Definition Exception.h:147
zypp::InputStream
Helper to create and pass std::istream.
Definition inputstream.h:57
zypp::InputStream::stream
std::istream & stream() const
The std::istream.
Definition inputstream.h:93
zypp::InputStream::path
const Pathname & path() const
Path to the input file or empty if no file.
Definition inputstream.h:111
zypp::UByteArray
Definition ByteArray.h:46
zypp::filesystem::Pathname
Pathname.
Definition Pathname.h:47
zypp::media::MediaBlockList
Definition mediablocklist.h:36
zypp::media::MediaBlockList::setRsum
void setRsum(size_t blkno, int rsl, unsigned int rs, size_t rspad=0)
set / verify the (weak) rolling checksum over a single block
Definition mediablocklist.cc:247
zypp::media::MediaBlockList::setFileChecksum
void setFileChecksum(std::string ctype, int cl, unsigned char *c)
set / verify the checksum over the whole file
Definition mediablocklist.cc:191
zypp::media::MediaBlockList::addBlock
size_t addBlock(off_t off, size_t size)
add a block with offset off and size size to the block list.
Definition mediablocklist.cc:183
zypp::media::MediaBlockList::setChecksum
void setChecksum(size_t blkno, const std::string &cstype, int csl, unsigned char *cs, size_t cspad=0)
set / verify the (strong) checksum over a single block
Definition mediablocklist.cc:228
zypp::media::MetaLinkParser::parseEnd
void parseEnd()
tells the parser that all chunks are now processed
Definition metalinkparser.cc:464
zypp::media::MetaLinkParser::pd
struct ml_parsedata * pd
Definition metalinkparser.h:81
zypp::media::MetaLinkParser::parse
void parse(const Pathname &filename)
parse a file consisting of metalink xml data
Definition metalinkparser.cc:428
zypp::media::MetaLinkParser::getBlockList
MediaBlockList getBlockList() const
return the block list from the parsed metalink data
Definition metalinkparser.cc:491
zypp::media::MetaLinkParser::parseBytes
void parseBytes(const char *bytes, size_t len)
parse a chunk of a file consisting of metalink xml data.
Definition metalinkparser.cc:453
zypp::media::MetaLinkParser::getSHA1BlockHashes
const std::vector< UByteArray > & getSHA1BlockHashes() const
Definition metalinkparser.cc:532
zypp::media::MetaLinkParser::~MetaLinkParser
~MetaLinkParser()
Definition metalinkparser.cc:422
zypp::media::MetaLinkParser::getZsyncBlockHashes
const std::vector< UByteArray > & getZsyncBlockHashes() const
Definition metalinkparser.cc:527
zypp::media::MetaLinkParser::MetaLinkParser
MetaLinkParser()
Definition metalinkparser.cc:418
zypp::media::MetaLinkParser::getMirrors
const std::vector< MetalinkMirror > & getMirrors() const
return the mirrors from the parsed metalink data
Definition metalinkparser.cc:486
zypp::media::MetaLinkParser::getUrls
std::vector< Url > getUrls() const
return the download urls from the parsed metalink data
Definition metalinkparser.cc:477
a
unsigned short a
Definition mediablocklist.cc:0
b
unsigned short b
Definition mediablocklist.cc:1
metalinkparser.h
str
String related utilities and Regular expression matching.
zypp::base
Definition Random.cc:7
zypp::base::NonCopyable
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
zypp::env
Namespace intended to collect all environment variables we use.
Definition Env.h:23
zypp::env::ZYPP_METALINK_DEBUG
bool ZYPP_METALINK_DEBUG()
Hack to circumvent the currently poor –root support.
Definition metalinkparser.cc:29
zypp::media
Definition MediaCD.cc:47
zypp::media::characterData
static void XMLCALL characterData(void *userData, const xmlChar *s, int len)
Definition metalinkparser.cc:406
zypp::media::ParserState
ParserState
Definition metalinkparser.cc:40
zypp::media::STATE_M4FILE
@ STATE_M4FILE
Definition metalinkparser.cc:45
zypp::media::STATE_HASH
@ STATE_HASH
Definition metalinkparser.cc:49
zypp::media::STATE_M4SIZE
@ STATE_M4SIZE
Definition metalinkparser.cc:47
zypp::media::NUMSTATES
@ NUMSTATES
Definition metalinkparser.cc:58
zypp::media::STATE_M4URL
@ STATE_M4URL
Definition metalinkparser.cc:57
zypp::media::STATE_START
@ STATE_START
Definition metalinkparser.cc:41
zypp::media::STATE_RESOURCES
@ STATE_RESOURCES
Definition metalinkparser.cc:55
zypp::media::STATE_PHASH
@ STATE_PHASH
Definition metalinkparser.cc:53
zypp::media::STATE_PIECES
@ STATE_PIECES
Definition metalinkparser.cc:51
zypp::media::STATE_SIZE
@ STATE_SIZE
Definition metalinkparser.cc:46
zypp::media::STATE_METALINK
@ STATE_METALINK
Definition metalinkparser.cc:42
zypp::media::STATE_VERIFICATION
@ STATE_VERIFICATION
Definition metalinkparser.cc:48
zypp::media::STATE_URL
@ STATE_URL
Definition metalinkparser.cc:56
zypp::media::STATE_FILE
@ STATE_FILE
Definition metalinkparser.cc:44
zypp::media::STATE_M4PHASH
@ STATE_M4PHASH
Definition metalinkparser.cc:54
zypp::media::STATE_M4HASH
@ STATE_M4HASH
Definition metalinkparser.cc:50
zypp::media::STATE_M4PIECES
@ STATE_M4PIECES
Definition metalinkparser.cc:52
zypp::media::STATE_FILES
@ STATE_FILES
Definition metalinkparser.cc:43
zypp::media::find_attr
static const char * find_attr(const char *txt, const xmlChar **atts)
Look up a xml attribute in the passed array atts.
Definition metalinkparser.cc:203
zypp::media::endElement
static void XMLCALL endElement(void *userData, const xmlChar *name)
Definition metalinkparser.cc:343
zypp::media::startElement
static void XMLCALL startElement(void *userData, const xmlChar *name, const xmlChar **atts)
Definition metalinkparser.cc:218
zypp::media::hexstr2bytes
UByteArray hexstr2bytes(const std::string &str)
Definition metalinkparser.cc:337
zypp::media::transitions
const std::unordered_map< ParserState, std::vector< transition > > & transitions()
Definition metalinkparser.cc:72
zypp::str::strToBool
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
Definition String.h:429
zypp::str::strtonum
TInt strtonum(const C_Str &str)
Parsing numbers from string.
zypp::media::ml_parsedata
Definition metalinkparser.cc:126
zypp::media::ml_parsedata::zsync
std::vector< UByteArray > zsync
Definition metalinkparser.cc:192
zypp::media::ml_parsedata::content
std::string content
Definition metalinkparser.cc:180
zypp::media::ml_parsedata::chksuml
int chksuml
Definition metalinkparser.cc:195
zypp::media::ml_parsedata::popState
void popState()
Definition metalinkparser.cc:159
zypp::media::ml_parsedata::parser
AutoDispose< xmlParserCtxtPtr > parser
Definition metalinkparser.cc:166
zypp::media::ml_parsedata::doTransition
void doTransition(const transition &t)
Definition metalinkparser.cc:151
zypp::media::ml_parsedata::ml_parsedata
ml_parsedata()
Definition metalinkparser.cc:127
zypp::media::ml_parsedata::urls
std::vector< MetalinkMirror > urls
Definition metalinkparser.cc:185
zypp::media::ml_parsedata::piece
std::vector< UByteArray > piece
Definition metalinkparser.cc:188
zypp::media::ml_parsedata::blksize
size_t blksize
Definition metalinkparser.cc:186
zypp::media::ml_parsedata::parentStates
std::stack< ParserState > parentStates
Definition metalinkparser.cc:169
zypp::media::ml_parsedata::gotfile
int gotfile
Definition metalinkparser.cc:183
zypp::media::ml_parsedata::state
ParserState state
Definition metalinkparser.cc:168
zypp::media::ml_parsedata::depth
int depth
Definition metalinkparser.cc:171
zypp::media::ml_parsedata::piecel
int piecel
Definition metalinkparser.cc:189
zypp::media::ml_parsedata::statedepth
int statedepth
Definition metalinkparser.cc:178
zypp::media::ml_parsedata::size
off_t size
Definition metalinkparser.cc:184
zypp::media::ml_parsedata::docontent
int docontent
Definition metalinkparser.cc:181
zypp::media::ml_parsedata::sha1
std::vector< UByteArray > sha1
Definition metalinkparser.cc:191
zypp::media::ml_parsedata::chksum
UByteArray chksum
Definition metalinkparser.cc:194
zypp::media::transition
Definition metalinkparser.cc:61
zypp::media::transition::docontent
int docontent
Definition metalinkparser.cc:64
zypp::media::transition::elementName
std::string elementName
Definition metalinkparser.cc:62
zypp::media::transition::transitionTo
ParserState transitionTo
Definition metalinkparser.cc:63
AutoDispose.h
ByteArray.h
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:424
Logger.h
DBG
#define DBG
Definition Logger.h:99
MIL
#define MIL
Definition Logger.h:100