23 #include <libxml/SAX2.h> 32 static bool val = [](){
33 const char *
env = getenv(
"ZYPP_METALINK_DEBUG");
73 const std::unordered_map<ParserState, std::vector<transition> > &
transitions () {
74 static std::unordered_map<ParserState, std::vector<transition> > map {
123 static void XMLCALL
startElement(
void *userData,
const xmlChar *name,
const xmlChar **atts);
124 static void XMLCALL
endElement(
void *userData,
const xmlChar *name);
125 static void XMLCALL
characterData(
void *userData,
const xmlChar *s,
int len);
126 static void XMLCALL
parseError(
void *userData,
const xmlError *error);
141 content.reserve( 256 );
144 memset(&sax, 0,
sizeof(sax));
151 #ifdef HAVE_LIBXML2_XMLCTXTSETERRORHANDLER 152 xmlCtxtSetErrorHandler ( parser,
parseError,
this );
154 xmlSetStructuredErrorFunc (
this, (xmlStructuredErrorFunc)
parseError );
159 #ifndef HAVE_LIBXML2_XMLCTXTSETERRORHANDLER 160 xmlSetStructuredErrorFunc (
nullptr,
nullptr );
165 parentStates.push( state );
173 state = parentStates.top();
198 std::vector<MetalinkMirror>
urls;
225 for (; *atts; atts += 2)
227 if (!strcmp(reinterpret_cast<const char*>(*atts), txt))
228 return reinterpret_cast<const char*
>(atts[1]);
234 startElement(
void *userData,
const xmlChar *name,
const xmlChar **atts)
247 const auto currStateTrs = trMap.find( pd->
state );
248 if ( currStateTrs == trMap.end() )
252 auto foundTr = std::find_if( currStateTrs->second.begin(), currStateTrs->second.end(), [name](
const auto &tr ){
253 return tr.elementName ==
reinterpret_cast<const char *
>(name);
256 if ( foundTr == currStateTrs->second.end() ) {
272 const char *priority =
find_attr(
"priority", atts);
273 const char *preference =
find_attr(
"preference", atts);
274 const char *maxconnections =
find_attr(
"maxconnections", atts);
276 auto &mirr = pd->
urls.emplace_back();
278 prio = str::strtonum<int>(priority);
280 prio = 101 - str::strtonum<int>(preference);
283 mirr.priority = prio;
285 if ( maxconnections )
286 mirr.maxConnections = str::strtonum<int>( maxconnections );
293 const char *type =
find_attr(
"type", atts);
294 const char *length =
find_attr(
"length", atts);
297 if (!type || !length)
302 blksize = str::strtonum<unsigned long>(length);
310 if (!strcmp(type,
"sha1") || !strcmp(type,
"sha-1"))
312 else if (!strcmp(type,
"zsync"))
324 const char *type =
find_attr(
"type", atts);
327 if ((!strcmp(type,
"sha1") || !strcmp(type,
"sha-1")) && pd->
chksuml < 20)
329 else if (!strcmp(type,
"sha256") || !strcmp(type,
"sha-256"))
341 const char *piece =
find_attr(
"piece", atts);
355 return Digest::hexStringToUByteArray(
str );
372 pd->
size = (off_t)str::strtonum<off_t>(pd->
content);
389 if ( !pieceHash.size() )
390 pieceHash.resize( pd->
piecel, 0 );
391 pd->
piece.push_back( pieceHash );
430 pd->
content.append( s, s+len );
433 static void XMLCALL
parseError(
void *userData,
const xmlError *error)
439 ERR <<
"Parse error in " << (pd->
_filename ? pd->
_filename->asString() : std::string(
"unknown filename")) <<
" : " << error->message << std::endl;
444 pd->
_lastError = std::make_exception_ptr (ex);
448 MetaLinkParser::MetaLinkParser()
480 while (is.
stream().good())
482 is.
stream().read(buf,
sizeof(buf));
486 MIL <<
"Parsed " <<
pd->
urls.size() <<
" mirrors from " << is.
path() << std::endl;
488 for (
const auto &mirr :
pd->
urls )
489 DBG <<
"- " << mirr.priority <<
" " << mirr.url << std::endl;
499 if (xmlParseChunk(
pd->
parser, buf, len, 0)) {
510 if (xmlParseChunk(
pd->
parser, NULL, 0, 1)) {
517 stable_sort(
pd->
urls.begin(),
pd->
urls.end(), [](
const auto &
a,
const auto &
b ){
518 return a.priority <
b.priority;
526 std::vector<Url> urls;
527 urls.reserve(
pd->
urls.size());
528 for (
const auto &mirr :
pd->
urls )
529 urls.push_back( mirr.url );
550 for (
size_t i = 0; i < nb; i++ )
558 size_t blkno = bl.
addBlock(off, size);
559 if ( i < pd->sha1.size())
562 if ( i < pd->zsync.size())
564 unsigned char *p =
pd->
zsync[i].data();
565 bl.
setRsum(blkno, 4, p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24,
pd->
blksize);
Namespace intended to collect all environment variables we use.
bool ZYPP_METALINK_DEBUG()
Hack to circumvent the currently poor –root support.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
String related utilities and Regular expression matching.
void remember(const Exception &old_r)
Store an other Exception as history.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.