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 {
123static void XMLCALL
startElement(
void *userData,
const xmlChar *name,
const xmlChar **atts);
124static void XMLCALL
endElement(
void *userData,
const xmlChar *name);
125static void XMLCALL
characterData(
void *userData,
const xmlChar *s,
int len);
126static void XMLCALL
parseError(
void *userData,
const xmlError *error);
144 memset(&sax, 0,
sizeof(sax));
151#ifdef HAVE_LIBXML2_XMLCTXTSETERRORHANDLER
154 xmlSetStructuredErrorFunc (
this, (xmlStructuredErrorFunc)
parseError );
159#ifndef HAVE_LIBXML2_XMLCTXTSETERRORHANDLER
160 xmlSetStructuredErrorFunc (
nullptr,
nullptr );
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]);
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();
283 mirr.priority = prio;
285 if ( maxconnections )
293 const char *type =
find_attr(
"type", atts);
294 const char *length =
find_attr(
"length", atts);
297 if (!type || !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 );
389 if ( !pieceHash.size() )
390 pieceHash.resize( pd->
piecel, 0 );
391 pd->
piece.push_back( pieceHash );
430 pd->
content.append( s, s+len );
433static 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);
460 pd->_filename = filename;
462 pd->_filename.reset();
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)) {
500 if (
pd->_lastError )
510 if (xmlParseChunk(
pd->parser, NULL, 0, 1)) {
511 if (
pd->_lastError )
516 if (
pd->urls.size() ) {
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 );
541 if (
pd->chksuml == 20)
543 else if (
pd->chksuml == 32)
545 if (
pd->size != off_t(-1) &&
pd->blksize)
547 size_t nb = (
pd->size +
pd->blksize - 1) /
pd->blksize;
549 size_t size =
pd->blksize;
550 for (
size_t i = 0; i < nb; i++ )
554 size =
pd->size %
pd->blksize;
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);
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
String related utilities and Regular expression matching.
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Namespace intended to collect all environment variables we use.
bool ZYPP_METALINK_DEBUG()
Hack to circumvent the currently poor –root support.
bool strToBool(const C_Str &str, bool default_r)
Parse str into a bool depending on the default value.
TInt strtonum(const C_Str &str)
Parsing numbers from string.
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.