mirror of https://github.com/aria2/aria2
2008-02-24 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Removed since they are not used. * src/Xml2MetalinkProcessor.{h, cc} * src/Socket.cc * src/SegmentSplitter.{h, cc} * test/Xml2MetalinkProcessorTest.ccpull/1/head
parent
a1f0d44c9f
commit
ac5332c5eb
|
@ -1,3 +1,11 @@
|
||||||
|
2008-02-24 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
Removed since they are not used.
|
||||||
|
* src/Xml2MetalinkProcessor.{h, cc}
|
||||||
|
* src/Socket.cc
|
||||||
|
* src/SegmentSplitter.{h, cc}
|
||||||
|
* test/Xml2MetalinkProcessorTest.cc
|
||||||
|
|
||||||
2008-02-24 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2008-02-24 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
Fixed the bug that prevents aria2 from stopping other than by pressing
|
Fixed the bug that prevents aria2 from stopping other than by pressing
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
/* <!-- copyright */
|
|
||||||
/*
|
|
||||||
* aria2 - The high speed download utility
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*
|
|
||||||
* In addition, as a special exception, the copyright holders give
|
|
||||||
* permission to link the code of portions of this program with the
|
|
||||||
* OpenSSL library under certain conditions as described in each
|
|
||||||
* individual source file, and distribute linked combinations
|
|
||||||
* including the two.
|
|
||||||
* You must obey the GNU General Public License in all respects
|
|
||||||
* for all of the code used other than OpenSSL. If you modify
|
|
||||||
* file(s) with this exception, you may extend this exception to your
|
|
||||||
* version of the file(s), but you are not obligated to do so. If you
|
|
||||||
* do not wish to do so, delete this exception statement from your
|
|
||||||
* version. If you delete this exception statement from all source
|
|
||||||
* files in the program, then also delete it here.
|
|
||||||
*/
|
|
||||||
/* copyright --> */
|
|
||||||
#include "SegmentSplitter.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "LogFactory.h"
|
|
||||||
|
|
||||||
SegmentSplitter::SegmentSplitter() {
|
|
||||||
logger = LogFactory::getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SegmentSplitter::split(Segment& seg, int cuid, Segment& s) const {
|
|
||||||
long long int nep = (s.ep-(s.sp+s.ds))/2+(s.sp+s.ds);
|
|
||||||
seg.cuid = cuid;
|
|
||||||
seg.sp = nep+1;
|
|
||||||
seg.ep = s.ep;
|
|
||||||
seg.ds = 0;
|
|
||||||
seg.speed = s.speed;
|
|
||||||
seg.finish = false;
|
|
||||||
s.ep = nep;
|
|
||||||
logger->debug(string("return new segment { "
|
|
||||||
"sp = "+Util::llitos(seg.sp)+", "+
|
|
||||||
"ep = "+Util::llitos(seg.ep)+", "+
|
|
||||||
"ds = "+Util::llitos(seg.ds)+", "+
|
|
||||||
"speed = "+Util::itos(seg.speed)+" } to "+
|
|
||||||
"cuid "+Util::llitos(cuid)).c_str());
|
|
||||||
logger->debug(string("update segment { "
|
|
||||||
"sp = "+Util::llitos(s.sp)+", "+
|
|
||||||
"ep = "+Util::llitos(s.ep)+", "+
|
|
||||||
"ds = "+Util::llitos(s.ds)+", "+
|
|
||||||
"speed = "+Util::itos(s.speed)+" } of "+
|
|
||||||
"cuid "+Util::llitos(s.cuid)).c_str());
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* <!-- copyright */
|
|
||||||
/*
|
|
||||||
* aria2 - The high speed download utility
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*
|
|
||||||
* In addition, as a special exception, the copyright holders give
|
|
||||||
* permission to link the code of portions of this program with the
|
|
||||||
* OpenSSL library under certain conditions as described in each
|
|
||||||
* individual source file, and distribute linked combinations
|
|
||||||
* including the two.
|
|
||||||
* You must obey the GNU General Public License in all respects
|
|
||||||
* for all of the code used other than OpenSSL. If you modify
|
|
||||||
* file(s) with this exception, you may extend this exception to your
|
|
||||||
* version of the file(s), but you are not obligated to do so. If you
|
|
||||||
* do not wish to do so, delete this exception statement from your
|
|
||||||
* version. If you delete this exception statement from all source
|
|
||||||
* files in the program, then also delete it here.
|
|
||||||
*/
|
|
||||||
/* copyright --> */
|
|
||||||
#ifndef _D_SEGMENT_SPLITTER_H_
|
|
||||||
#define _D_SEGMENT_SPLITTER_H_
|
|
||||||
|
|
||||||
#include "Segment.h"
|
|
||||||
#include "Logger.h"
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
class SegmentSplitter {
|
|
||||||
protected:
|
|
||||||
long long int minSegmentSize;
|
|
||||||
const Logger* logger;
|
|
||||||
|
|
||||||
void split(Segment& seg, int cuid, Segment& s) const;
|
|
||||||
public:
|
|
||||||
SegmentSplitter();
|
|
||||||
virtual ~SegmentSplitter() {}
|
|
||||||
virtual bool splitSegment(Segment& newSegment, int cuid, Segments& segments) = 0;
|
|
||||||
void setMinSegmentSize(long long int size) { minSegmentSize = size; }
|
|
||||||
long long int getMinSegmentSize() const { return minSegmentSize; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _D_SEGMENT_SPLITTER_H_
|
|
123
src/Socket.cc
123
src/Socket.cc
|
@ -1,123 +0,0 @@
|
||||||
/* <!-- copyright */
|
|
||||||
/*
|
|
||||||
* aria2 - The high speed download utility
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*
|
|
||||||
* In addition, as a special exception, the copyright holders give
|
|
||||||
* permission to link the code of portions of this program with the
|
|
||||||
* OpenSSL library under certain conditions as described in each
|
|
||||||
* individual source file, and distribute linked combinations
|
|
||||||
* including the two.
|
|
||||||
* You must obey the GNU General Public License in all respects
|
|
||||||
* for all of the code used other than OpenSSL. If you modify
|
|
||||||
* file(s) with this exception, you may extend this exception to your
|
|
||||||
* version of the file(s), but you are not obligated to do so. If you
|
|
||||||
* do not wish to do so, delete this exception statement from your
|
|
||||||
* version. If you delete this exception statement from all source
|
|
||||||
* files in the program, then also delete it here.
|
|
||||||
*/
|
|
||||||
/* copyright --> */
|
|
||||||
#include "Socket.h"
|
|
||||||
|
|
||||||
Socket::Socket() {
|
|
||||||
core = new SocketCore();
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket::Socket(const Socket& s) {
|
|
||||||
core = s.core;
|
|
||||||
core->use++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket::Socket(SocketCore* core) {
|
|
||||||
this->core = core;
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket::~Socket() {
|
|
||||||
core->use--;
|
|
||||||
if(core->use == 0) {
|
|
||||||
delete core;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket& Socket::operator=(const Socket& s) {
|
|
||||||
if(this != &s) {
|
|
||||||
core->use--;
|
|
||||||
if(core->use == 0) {
|
|
||||||
delete core;
|
|
||||||
}
|
|
||||||
core = s.core;
|
|
||||||
core->use++;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::beginListen(int32_t port) const {
|
|
||||||
core->beginListen(port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::getAddrInfo(pair<string, int32_t>& addrinfo) const {
|
|
||||||
core->getAddrInfo(addrinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::getPeerInfo(pair<string, int32_t>& peerinfo) const {
|
|
||||||
core->getPeerInfo(peerinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket* Socket::acceptConnection() const {
|
|
||||||
return new Socket(core->acceptConnection());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::establishConnection(const string& host, int32_t port) const {
|
|
||||||
core->establishConnection(host, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::setBlockingMode() const {
|
|
||||||
core->setBlockingMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::closeConnection() const {
|
|
||||||
core->closeConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Socket::isWritable(int32_t timeout) const {
|
|
||||||
return core->isWritable(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Socket::isReadable(int32_t timeout) const {
|
|
||||||
return core->isReadable(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::writeData(const char* data, int32_t len) const {
|
|
||||||
core->writeData(data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::writeData(const string& str) const {
|
|
||||||
core->writeData(str.c_str(), str.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::readData(char* data, int32_t& len) const {
|
|
||||||
core->readData(data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::peekData(char* data, int32_t& len) const {
|
|
||||||
core->peekData(data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Socket::initiateSecureConnection() const {
|
|
||||||
core->initiateSecureConnection();
|
|
||||||
}
|
|
|
@ -1,342 +0,0 @@
|
||||||
/* <!-- copyright */
|
|
||||||
/*
|
|
||||||
* aria2 - The high speed download utility
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*
|
|
||||||
* In addition, as a special exception, the copyright holders give
|
|
||||||
* permission to link the code of portions of this program with the
|
|
||||||
* OpenSSL library under certain conditions as described in each
|
|
||||||
* individual source file, and distribute linked combinations
|
|
||||||
* including the two.
|
|
||||||
* You must obey the GNU General Public License in all respects
|
|
||||||
* for all of the code used other than OpenSSL. If you modify
|
|
||||||
* file(s) with this exception, you may extend this exception to your
|
|
||||||
* version of the file(s), but you are not obligated to do so. If you
|
|
||||||
* do not wish to do so, delete this exception statement from your
|
|
||||||
* version. If you delete this exception statement from all source
|
|
||||||
* files in the program, then also delete it here.
|
|
||||||
*/
|
|
||||||
/* copyright --> */
|
|
||||||
#include "Xml2MetalinkProcessor.h"
|
|
||||||
#include "DlAbortEx.h"
|
|
||||||
#include "Util.h"
|
|
||||||
#include "BinaryStream.h"
|
|
||||||
#include <libxml/parser.h>
|
|
||||||
#include <libxml/xpath.h>
|
|
||||||
#include <libxml/xpathInternals.h>
|
|
||||||
|
|
||||||
Xml2MetalinkProcessor::Xml2MetalinkProcessor():doc(0), context(0) {}
|
|
||||||
|
|
||||||
Xml2MetalinkProcessor::~Xml2MetalinkProcessor() {
|
|
||||||
release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Xml2MetalinkProcessor::release() {
|
|
||||||
if(context) {
|
|
||||||
xmlXPathFreeContext(context);
|
|
||||||
context = 0;
|
|
||||||
}
|
|
||||||
if(doc) {
|
|
||||||
xmlFreeDoc(doc);
|
|
||||||
doc = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MetalinkerHandle Xml2MetalinkProcessor::parseFile(const string& filename) {
|
|
||||||
release();
|
|
||||||
doc = xmlParseFile(filename.c_str());
|
|
||||||
if(!doc) {
|
|
||||||
throw new DlAbortEx("Cannot parse metalink file %s", filename.c_str());
|
|
||||||
}
|
|
||||||
return processDoc(doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
MetalinkerHandle Xml2MetalinkProcessor::parseFromBinaryStream(const BinaryStreamHandle& binaryStream) {
|
|
||||||
release();
|
|
||||||
int32_t bufSize = 4096;
|
|
||||||
unsigned char buf[bufSize];
|
|
||||||
|
|
||||||
int32_t res = binaryStream->readData(buf, 4, 0);
|
|
||||||
if(res != 4) {
|
|
||||||
throw new DlAbortEx("Too small data for metalink parsing.");
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlParserCtxtPtr ctx = xmlCreatePushParserCtxt(0, 0, (const char*)buf, res, 0);
|
|
||||||
try {
|
|
||||||
int64_t readOffset = res;
|
|
||||||
while(1) {
|
|
||||||
int32_t res = binaryStream->readData(buf, bufSize, readOffset);
|
|
||||||
if(res == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(xmlParseChunk(ctx, (const char*)buf, res, 0) != 0) {
|
|
||||||
throw new DlAbortEx("Cannot parse metalink file");
|
|
||||||
}
|
|
||||||
readOffset += res;
|
|
||||||
}
|
|
||||||
xmlParseChunk(ctx, (const char*)buf, 0, 1);
|
|
||||||
doc = ctx->myDoc;
|
|
||||||
|
|
||||||
xmlFreeParserCtxt(ctx);
|
|
||||||
} catch(Exception* e) {
|
|
||||||
xmlFreeParserCtxt(ctx);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!doc) {
|
|
||||||
throw new DlAbortEx("Cannot parse metalink file");
|
|
||||||
}
|
|
||||||
return processDoc(doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
MetalinkerHandle Xml2MetalinkProcessor::processDoc(xmlDocPtr doc)
|
|
||||||
{
|
|
||||||
context = xmlXPathNewContext(doc);
|
|
||||||
if(!context) {
|
|
||||||
throw new DlAbortEx("Cannot create new xpath context");
|
|
||||||
}
|
|
||||||
string defaultNamespace = "http://www.metalinker.org/";
|
|
||||||
if(xmlXPathRegisterNs(context, (xmlChar*)"m",
|
|
||||||
(xmlChar*)defaultNamespace.c_str()) != 0) {
|
|
||||||
throw new DlAbortEx("Cannot register namespace %s",
|
|
||||||
defaultNamespace.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
string xpath = "/m:metalink/m:files/m:file";
|
|
||||||
MetalinkerHandle metalinker(new Metalinker());
|
|
||||||
for(uint32_t index = 1; 1; index++) {
|
|
||||||
MetalinkEntryHandle entry = getEntry(xpath+"["+Util::uitos(index)+"]");
|
|
||||||
if(!entry.get()) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
metalinker->entries.push_back(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return metalinker;
|
|
||||||
}
|
|
||||||
|
|
||||||
MetalinkEntryHandle Xml2MetalinkProcessor::getEntry(const string& xpath) {
|
|
||||||
xmlXPathObjectPtr result = xpathEvaluation(xpath);
|
|
||||||
if(!result) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
xmlNodeSetPtr nodeSet = result->nodesetval;
|
|
||||||
xmlNodePtr node = nodeSet->nodeTab[0];
|
|
||||||
string filename = Util::trim(xmlAttribute(node, "name"));
|
|
||||||
xmlXPathFreeObject(result);
|
|
||||||
|
|
||||||
MetalinkEntryHandle entry(new MetalinkEntry());
|
|
||||||
|
|
||||||
FileEntryHandle fileEntry = new FileEntry(filename, 0, 0);
|
|
||||||
|
|
||||||
string sizeStr = Util::trim(xpathContent(xpath+"/m:size"));
|
|
||||||
if(sizeStr == "") {
|
|
||||||
fileEntry->setLength(0);
|
|
||||||
} else {
|
|
||||||
fileEntry->setLength(strtoll(sizeStr.c_str(), 0, 10));
|
|
||||||
}
|
|
||||||
entry->file = fileEntry;
|
|
||||||
entry->version = Util::trim(xpathContent(xpath+"/m:version"));
|
|
||||||
entry->language = Util::trim(xpathContent(xpath+"/m:language"));
|
|
||||||
entry->os = Util::trim(xpathContent(xpath+"/m:os"));
|
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
|
||||||
xmlXPathObjectPtr hashPathObj = xpathEvaluation(xpath+"/m:verification/m:hash");
|
|
||||||
if(hashPathObj) {
|
|
||||||
xmlNodeSetPtr nodeSet = hashPathObj->nodesetval;
|
|
||||||
for(int32_t i = 0; i < nodeSet->nodeNr; ++i) {
|
|
||||||
xmlNodePtr node = nodeSet->nodeTab[i];
|
|
||||||
string algo = Util::trim(xmlAttribute(node, "type"));
|
|
||||||
if(MessageDigestContext::supports(algo)) {
|
|
||||||
entry->checksum = new Checksum(algo, Util::trim(xmlContent(node)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xmlXPathFreeObject(hashPathObj);
|
|
||||||
|
|
||||||
string piecesPath = xpath+"/m:verification/m:pieces";
|
|
||||||
xmlXPathObjectPtr pieceHashPathObj = xpathEvaluation(piecesPath);
|
|
||||||
if(pieceHashPathObj) {
|
|
||||||
xmlNodeSetPtr nodeSet = pieceHashPathObj->nodesetval;
|
|
||||||
for(int32_t i = 0; i < nodeSet->nodeNr; ++i) {
|
|
||||||
xmlNodePtr node = nodeSet->nodeTab[i];
|
|
||||||
string algo = Util::trim(xmlAttribute(node, "type"));
|
|
||||||
if(MessageDigestContext::supports(algo)) {
|
|
||||||
entry->chunkChecksum = getPieceHash(piecesPath+"[@type=\""+algo+"\"]",
|
|
||||||
entry->getLength());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xmlXPathFreeObject(pieceHashPathObj);
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
|
|
||||||
string resourcesPath = xpath+"/m:resources[@maxconnections]";
|
|
||||||
xmlXPathObjectPtr resourcesPathObj = xpathEvaluation(resourcesPath);
|
|
||||||
if(resourcesPathObj) {
|
|
||||||
xmlNodeSetPtr nodeSet = resourcesPathObj->nodesetval;
|
|
||||||
xmlNodePtr node = nodeSet->nodeTab[0];
|
|
||||||
int32_t maxConnections = strtol(Util::trim(xmlAttribute(node, "maxconnections")).c_str(), 0, 10);
|
|
||||||
entry->maxConnections = maxConnections;
|
|
||||||
}
|
|
||||||
xmlXPathFreeObject(resourcesPathObj);
|
|
||||||
|
|
||||||
for(uint32_t index = 1; 1; index++) {
|
|
||||||
MetalinkResourceHandle resource(getResource(xpath+"/m:resources/m:url["+Util::uitos(index)+"]"));
|
|
||||||
if(!resource.get()) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
entry->resources.push_back(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
|
||||||
ChunkChecksumHandle Xml2MetalinkProcessor::getPieceHash(const string& xpath,
|
|
||||||
int64_t totalSize)
|
|
||||||
{
|
|
||||||
xmlXPathObjectPtr result = xpathEvaluation(xpath);
|
|
||||||
if(!result) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
xmlNodeSetPtr nodeSet = result->nodesetval;
|
|
||||||
xmlNodePtr node = nodeSet->nodeTab[0];
|
|
||||||
|
|
||||||
int64_t checksumLength = STRTOLL(Util::trim(xmlAttribute(node, "length")).c_str());
|
|
||||||
string algoString = Util::trim(xmlAttribute(node, "type"));
|
|
||||||
xmlXPathFreeObject(result);
|
|
||||||
|
|
||||||
if(!MessageDigestContext::supports(algoString)) {
|
|
||||||
// unknown checksum type
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Strings checksums;
|
|
||||||
uint64_t numPiece = (totalSize+checksumLength-1)/checksumLength;
|
|
||||||
for(uint64_t i = 0; i < numPiece; ++i) {
|
|
||||||
string pieceHash = Util::trim(xpathContent(xpath+"/m:hash[@piece=\""+Util::ullitos(i)+"\"]"));
|
|
||||||
if(pieceHash == "") {
|
|
||||||
throw new DlAbortEx("Piece hash missing. index=%s", Util::ullitos(i).c_str());
|
|
||||||
}
|
|
||||||
checksums.push_back(pieceHash);
|
|
||||||
}
|
|
||||||
return new ChunkChecksum(algoString, checksums, checksumLength);
|
|
||||||
}
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
|
|
||||||
MetalinkResourceHandle Xml2MetalinkProcessor::getResource(const string& xpath) {
|
|
||||||
xmlXPathObjectPtr result = xpathEvaluation(xpath);
|
|
||||||
if(!result) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
MetalinkResourceHandle resource(new MetalinkResource());
|
|
||||||
|
|
||||||
xmlNodeSetPtr nodeSet = result->nodesetval;
|
|
||||||
xmlNodePtr node = nodeSet->nodeTab[0];
|
|
||||||
string type = Util::trim(xmlAttribute(node, "type"));
|
|
||||||
|
|
||||||
if(type == "ftp") {
|
|
||||||
resource->type = MetalinkResource::TYPE_FTP;
|
|
||||||
} else if(type == "http") {
|
|
||||||
resource->type = MetalinkResource::TYPE_HTTP;
|
|
||||||
} else if(type == "https") {
|
|
||||||
resource->type = MetalinkResource::TYPE_HTTPS;
|
|
||||||
} else if(type == "bittorrent") {
|
|
||||||
resource->type = MetalinkResource::TYPE_BITTORRENT;
|
|
||||||
} else {
|
|
||||||
resource->type = MetalinkResource::TYPE_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
string pref = Util::trim(xmlAttribute(node, "preference"));
|
|
||||||
if(pref.empty()) {
|
|
||||||
resource->preference = 100;
|
|
||||||
} else {
|
|
||||||
resource->preference = STRTOLL(pref.c_str());
|
|
||||||
}
|
|
||||||
resource->location = Util::toUpper(Util::trim(xmlAttribute(node, "location")));
|
|
||||||
|
|
||||||
resource->url = Util::trim(xmlContent(node));
|
|
||||||
|
|
||||||
{
|
|
||||||
string cnn = Util::trim(xmlAttribute(node, "maxconnections"));
|
|
||||||
if(!cnn.empty()) {
|
|
||||||
resource->maxConnections = strtol(cnn.c_str(), 0, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlXPathFreeObject(result);
|
|
||||||
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlXPathObjectPtr Xml2MetalinkProcessor::xpathEvaluation(const string& xpath) {
|
|
||||||
xmlXPathObjectPtr result = xmlXPathEvalExpression((xmlChar*)xpath.c_str(),
|
|
||||||
context);
|
|
||||||
if(!result) {
|
|
||||||
throw new DlAbortEx("Cannot evaluate xpath %s", xpath.c_str());
|
|
||||||
}
|
|
||||||
if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
|
|
||||||
xmlXPathFreeObject(result);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
string Xml2MetalinkProcessor::xmlAttribute(xmlNodePtr node, const string& attrName) {
|
|
||||||
xmlChar* temp = xmlGetNoNsProp(node, (xmlChar*)attrName.c_str());
|
|
||||||
if(!temp) {
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
string attr = (char*)temp;
|
|
||||||
xmlFree(temp);
|
|
||||||
return attr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string Xml2MetalinkProcessor::xmlContent(xmlNodePtr node) {
|
|
||||||
xmlChar* temp = xmlNodeGetContent(node);
|
|
||||||
if(!temp) {
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
string content = (char*)temp;
|
|
||||||
xmlFree(temp);
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string Xml2MetalinkProcessor::xpathContent(const string& xpath) {
|
|
||||||
xmlXPathObjectPtr result = xpathEvaluation(xpath);
|
|
||||||
if(!result) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
xmlNodeSetPtr nodeSet = result->nodesetval;
|
|
||||||
xmlNodePtr node = nodeSet->nodeTab[0]->children;
|
|
||||||
string content = (char*)node->content;
|
|
||||||
xmlXPathFreeObject(result);
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Xml2MetalinkProcessor::xpathExists(const string& xpath) {
|
|
||||||
xmlXPathObjectPtr result = xpathEvaluation(xpath);
|
|
||||||
bool retval = true;
|
|
||||||
if(!result) {
|
|
||||||
retval = false;
|
|
||||||
}
|
|
||||||
xmlXPathFreeObject(result);
|
|
||||||
return retval;
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
/* <!-- copyright */
|
|
||||||
/*
|
|
||||||
* aria2 - The high speed download utility
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 Tatsuhiro Tsujikawa
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*
|
|
||||||
* In addition, as a special exception, the copyright holders give
|
|
||||||
* permission to link the code of portions of this program with the
|
|
||||||
* OpenSSL library under certain conditions as described in each
|
|
||||||
* individual source file, and distribute linked combinations
|
|
||||||
* including the two.
|
|
||||||
* You must obey the GNU General Public License in all respects
|
|
||||||
* for all of the code used other than OpenSSL. If you modify
|
|
||||||
* file(s) with this exception, you may extend this exception to your
|
|
||||||
* version of the file(s), but you are not obligated to do so. If you
|
|
||||||
* do not wish to do so, delete this exception statement from your
|
|
||||||
* version. If you delete this exception statement from all source
|
|
||||||
* files in the program, then also delete it here.
|
|
||||||
*/
|
|
||||||
/* copyright --> */
|
|
||||||
#ifndef _D_XML2_METALINK_PROCESSOR_H_
|
|
||||||
#define _D_XML2_METALINK_PROCESSOR_H_
|
|
||||||
|
|
||||||
#include "MetalinkProcessor.h"
|
|
||||||
#include <libxml/parser.h>
|
|
||||||
#include <libxml/xpath.h>
|
|
||||||
|
|
||||||
class BinaryStream;
|
|
||||||
typedef SharedHandle<BinaryStream> BinaryStreamHandle;
|
|
||||||
|
|
||||||
class Xml2MetalinkProcessor : public MetalinkProcessor {
|
|
||||||
private:
|
|
||||||
xmlDocPtr doc;
|
|
||||||
xmlXPathContextPtr context;
|
|
||||||
|
|
||||||
MetalinkEntryHandle getEntry(const string& xpath);
|
|
||||||
MetalinkResourceHandle getResource(const string& xpath);
|
|
||||||
|
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
|
||||||
ChunkChecksumHandle getPieceHash(const string& xpath,
|
|
||||||
int64_t totalSize);
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
|
|
||||||
xmlXPathObjectPtr xpathEvaluation(const string& xpath);
|
|
||||||
string xpathContent(const string& xpath);
|
|
||||||
string xmlAttribute(xmlNodePtr node, const string& attrName);
|
|
||||||
string xmlContent(xmlNodePtr node);
|
|
||||||
bool xpathExists(const string& xpath);
|
|
||||||
|
|
||||||
void release();
|
|
||||||
|
|
||||||
MetalinkerHandle processDoc(xmlDocPtr doc);
|
|
||||||
|
|
||||||
public:
|
|
||||||
Xml2MetalinkProcessor();
|
|
||||||
virtual ~Xml2MetalinkProcessor();
|
|
||||||
|
|
||||||
virtual MetalinkerHandle parseFile(const string& filename);
|
|
||||||
|
|
||||||
virtual MetalinkerHandle parseFromBinaryStream(const BinaryStreamHandle& binaryStream);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // _D_XML2_METALINK_PROCESSOR_H_
|
|
|
@ -1,138 +0,0 @@
|
||||||
#include "Xml2MetalinkProcessor.h"
|
|
||||||
#include "Exception.h"
|
|
||||||
#include "DefaultDiskWriter.h"
|
|
||||||
#include <cppunit/extensions/HelperMacros.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class Xml2MetalinkProcessorTest:public CppUnit::TestFixture {
|
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE(Xml2MetalinkProcessorTest);
|
|
||||||
CPPUNIT_TEST(testParseFile);
|
|
||||||
CPPUNIT_TEST(testParseFromBinaryStream);
|
|
||||||
CPPUNIT_TEST_SUITE_END();
|
|
||||||
private:
|
|
||||||
|
|
||||||
public:
|
|
||||||
void setUp() {
|
|
||||||
xmlInitParser();
|
|
||||||
}
|
|
||||||
void tearDown() {
|
|
||||||
xmlCleanupParser();
|
|
||||||
}
|
|
||||||
|
|
||||||
void testParseFile();
|
|
||||||
void testParseFromBinaryStream();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
CPPUNIT_TEST_SUITE_REGISTRATION( Xml2MetalinkProcessorTest );
|
|
||||||
|
|
||||||
void Xml2MetalinkProcessorTest::testParseFile() {
|
|
||||||
Xml2MetalinkProcessor proc;
|
|
||||||
try {
|
|
||||||
MetalinkerHandle metalinker = proc.parseFile("test.xml");
|
|
||||||
|
|
||||||
MetalinkEntries::iterator entryItr = metalinker->entries.begin();
|
|
||||||
MetalinkEntryHandle entry1 = *entryItr;
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), entry1->getPath());
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int64_t)0, entry1->getLength());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("0.5.2"), entry1->version);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("en-US"), entry1->language);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("Linux-x86"), entry1->os);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int32_t)1, entry1->maxConnections);
|
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("a96cf3f0266b91d87d5124cf94326422800b627d"),
|
|
||||||
entry1->checksum->getMessageDigest());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("sha1"), entry1->checksum->getAlgo());
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
MetalinkResources::iterator resourceItr1 = entry1->resources.begin();
|
|
||||||
MetalinkResourceHandle resource1 = *resourceItr1;
|
|
||||||
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_FTP, resource1->type);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("JP"), resource1->location);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int32_t)100, resource1->preference);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("ftp://ftphost/aria2-0.5.2.tar.bz2"),
|
|
||||||
resource1->url);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int32_t)1, resource1->maxConnections);
|
|
||||||
|
|
||||||
resourceItr1++;
|
|
||||||
MetalinkResourceHandle resource2 = *resourceItr1;
|
|
||||||
CPPUNIT_ASSERT_EQUAL(MetalinkResource::TYPE_HTTP, resource2->type);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("US"), resource2->location);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int32_t)100, resource2->preference);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("http://httphost/aria2-0.5.2.tar.bz2"),
|
|
||||||
resource2->url);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int32_t)-1, resource2->maxConnections);
|
|
||||||
|
|
||||||
entryItr++;
|
|
||||||
|
|
||||||
MetalinkEntryHandle entry2 = *entryItr;
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.1.tar.bz2"), entry2->getPath());
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int64_t)345689, entry2->getLength());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("0.5.1"), entry2->version);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("ja-JP"), entry2->language);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("Linux-m68k"), entry2->os);
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int32_t)-1, entry2->maxConnections);
|
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
|
|
||||||
entry2->checksum->getMessageDigest());
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int32_t)2, entry2->chunkChecksum->countChecksum());
|
|
||||||
CPPUNIT_ASSERT_EQUAL((int32_t)262144, entry2->chunkChecksum->getChecksumLength());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("179463a88d79cbf0b1923991708aead914f26142"),
|
|
||||||
entry2->chunkChecksum->getChecksum(0));
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("fecf8bc9a1647505fe16746f94e97a477597dbf3"),
|
|
||||||
entry2->chunkChecksum->getChecksum(1));
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("sha1"), entry2->checksum->getAlgo());
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
|
|
||||||
entryItr++;
|
|
||||||
|
|
||||||
// test case: verification hash is not provided
|
|
||||||
MetalinkEntryHandle entry3 = *entryItr;
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("NoVerificationHash"), entry3->getPath());
|
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
|
||||||
CPPUNIT_ASSERT(entry3->checksum.isNull());
|
|
||||||
CPPUNIT_ASSERT(entry3->chunkChecksum.isNull());
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
|
|
||||||
entryItr++;
|
|
||||||
|
|
||||||
// test case: unsupported verification hash is included
|
|
||||||
MetalinkEntryHandle entry4 = *entryItr;
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("UnsupportedVerificationHashTypeIncluded"), entry4->getPath());
|
|
||||||
#ifdef ENABLE_MESSAGE_DIGEST
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("sha1"),
|
|
||||||
entry4->checksum->getAlgo());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
|
|
||||||
entry4->checksum->getMessageDigest());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("sha1"),
|
|
||||||
entry4->chunkChecksum->getAlgo());
|
|
||||||
#endif // ENABLE_MESSAGE_DIGEST
|
|
||||||
|
|
||||||
|
|
||||||
} catch(Exception* e) {
|
|
||||||
CPPUNIT_FAIL(e->getMsg());
|
|
||||||
delete e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Xml2MetalinkProcessorTest::testParseFromBinaryStream() {
|
|
||||||
Xml2MetalinkProcessor proc;
|
|
||||||
try {
|
|
||||||
DefaultDiskWriterHandle dw = new DefaultDiskWriter();
|
|
||||||
dw->openExistingFile("test.xml");
|
|
||||||
|
|
||||||
MetalinkerHandle metalinker = proc.parseFromBinaryStream(dw);
|
|
||||||
|
|
||||||
dw->closeFile();
|
|
||||||
|
|
||||||
MetalinkEntries::iterator entryItr = metalinker->entries.begin();
|
|
||||||
MetalinkEntryHandle entry1 = *entryItr;
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("aria2-0.5.2.tar.bz2"), entry1->getPath());
|
|
||||||
} catch(Exception* e) {
|
|
||||||
cerr << *e;
|
|
||||||
CPPUNIT_FAIL(e->getMsg());
|
|
||||||
delete e;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue