util::divide now takes iterators as arguments.

pull/2/head
Tatsuhiro Tsujikawa 2011-11-03 23:09:03 +09:00
parent 118626afc4
commit 6267676e8b
13 changed files with 151 additions and 125 deletions

View File

@ -35,6 +35,7 @@
#include "ExpatMetalinkProcessor.h"
#include <cstdio>
#include <cstring>
#include "DefaultDiskWriter.h"
#include "MetalinkParserStateMachine.h"
@ -63,17 +64,18 @@ public:
} // namespace
namespace {
template<typename InputIterator>
void splitNsName
(std::string& localname, std::string& prefix, std::string& nsUri,
const std::string& nsName)
InputIterator first, InputIterator last)
{
std::pair<std::string, std::string> nsNamePair;
util::divide(nsNamePair, nsName, '\t');
if(nsNamePair.second.empty()) {
localname = nsNamePair.first;
std::pair<Scip, Scip> nsNamePair;
util::divide(nsNamePair, first, last, '\t');
if(nsNamePair.second.first == nsNamePair.second.second) {
localname.assign(nsNamePair.first.first, nsNamePair.first.second);
} else {
nsUri = nsNamePair.first;
localname = nsNamePair.second;
nsUri.assign(nsNamePair.first.first, nsNamePair.first.second);
localname.assign(nsNamePair.second.first, nsNamePair.second.second);
}
}
} // namespace
@ -87,29 +89,22 @@ void mlStartElement(void* userData, const char* nsName, const char** attrs)
if(attrs) {
const char** p = attrs;
while(*p != 0) {
std::string attrNsName = *p++;
const char* attrNsName = *p++;
if(*p == 0) {
break;
}
std::string value = *p++;
std::pair<std::string, std::string> nsNamePair;
util::divide(nsNamePair, attrNsName, '\t');
XmlAttr xa;
if(nsNamePair.second.empty()) {
xa.localname = nsNamePair.first;
} else {
xa.nsUri = nsNamePair.first;
xa.localname = nsNamePair.second;
}
xa.value = value;
splitNsName(xa.localname, xa.prefix, xa.nsUri,
attrNsName, attrNsName+strlen(attrNsName));
const char* value = *p++;
xa.value.assign(value, value+strlen(value));
xmlAttrs.push_back(xa);
}
}
std::string localname;
std::string prefix;
std::string nsUri;
splitNsName(localname, prefix, nsUri, nsName);
splitNsName(localname, prefix, nsUri, nsName, nsName+strlen(nsName));
sd->stm_->beginElement(localname, prefix, nsUri, xmlAttrs);
if(sd->stm_->needsCharactersBuffering()) {
sd->charactersStack_.push_front(A2STR::NIL);
@ -123,7 +118,7 @@ void mlEndElement(void* userData, const char* nsName)
std::string localname;
std::string prefix;
std::string nsUri;
splitNsName(localname, prefix, nsUri, nsName);
splitNsName(localname, prefix, nsUri, nsName, nsName+strlen(nsName));
SessionData* sd = reinterpret_cast<SessionData*>(userData);
std::string characters;

View File

@ -435,9 +435,9 @@ unsigned int FtpConnection::receiveSizeResponse(uint64_t& size)
std::pair<unsigned int, std::string> response;
if(bulkReceiveResponse(response)) {
if(response.first == 213) {
std::pair<std::string, std::string> rp;
util::divide(rp, response.second, ' ');
size = util::parseULLInt(rp.second.begin(), rp.second.end());
std::pair<Scip, Scip> rp;
util::divide(rp, response.second.begin(), response.second.end(), ' ');
size = util::parseULLInt(rp.second.first, rp.second.second);
}
return response.first;
} else {

View File

@ -249,9 +249,10 @@ std::string HttpResponse::getContentType() const
if(!httpHeader_) {
return A2STR::NIL;
} else {
std::pair<std::string, std::string> p;
util::divide(p, httpHeader_->getFirst(HttpHeader::CONTENT_TYPE), ';');
return p.first;
const std::string& ctype = httpHeader_->getFirst(HttpHeader::CONTENT_TYPE);
std::string::const_iterator i = std::find(ctype.begin(), ctype.end(), ';');
Scip p = util::stripIter(ctype.begin(), i);
return std::string(p.first, p.second);
}
}

View File

@ -203,19 +203,26 @@ bool HttpServer::authenticate()
return true;
}
std::string authHeader = lastRequestHeader_->getFirst("Authorization");
const std::string& authHeader = lastRequestHeader_->getFirst("Authorization");
if(authHeader.empty()) {
return false;
}
std::pair<std::string, std::string> p;
util::divide(p, authHeader, ' ');
if(p.first != "Basic") {
std::pair<Scip, Scip> p;
util::divide(p, authHeader.begin(), authHeader.end(), ' ');
const char authMethod[] = "Basic";
if(!std::distance(p.first.first, p.first.second) == sizeof(authMethod) ||
!std::equal(p.first.first, p.first.second, &authMethod[0])) {
return false;
}
std::string userpass = Base64::decode(p.second);
std::pair<std::string, std::string> userpassPair;
util::divide(userpassPair, userpass, ':');
return username_ == userpassPair.first && password_ == userpassPair.second;
std::string userpass = Base64::decode(std::string(p.second.first,
p.second.second));
util::divide(p, userpass.begin(), userpass.end(), ':');
return username_.size() ==
static_cast<size_t>(std::distance(p.first.first, p.first.second)) &&
std::equal(username_.begin(), username_.end(), p.first.first) &&
password_.size() ==
static_cast<size_t>(std::distance(p.second.first, p.second.second)) &&
std::equal(password_.begin(), password_.end(), p.second.first);
}
void HttpServer::setUsernamePassword

View File

@ -365,11 +365,13 @@ ChecksumOptionHandler::~ChecksumOptionHandler() {}
void ChecksumOptionHandler::parseArg(Option& option, const std::string& optarg)
{
std::pair<std::string, std::string> p;
util::divide(p, optarg, '=');
util::lowercase(p.first);
util::lowercase(p.second);
if(!MessageDigest::isValidHash(p.first, p.second)) {
std::pair<Scip, Scip> p;
util::divide(p, optarg.begin(), optarg.end(), '=');
std::string hashType(p.first.first, p.first.second);
std::string hexDigest(p.second.first, p.second.second);
util::lowercase(hashType);
util::lowercase(hexDigest);
if(!MessageDigest::isValidHash(hashType, hexDigest)) {
throw DL_ABORT_EX(_("Unrecognized checksum"));
}
option.put(pref_, optarg);

View File

@ -184,14 +184,15 @@ void OptionParser::parse(Option& option, std::istream& is) const
if(util::startsWith(line, A2STR::SHARP_C)) {
continue;
}
std::pair<std::string, std::string> nv;
util::divide(nv, line, '=');
if(nv.first.empty()) {
std::pair<Scip, Scip> nv;
util::divide(nv, line.begin(), line.end(), '=');
if(nv.first.first == nv.first.second) {
continue;
}
const SharedHandle<OptionHandler>& handler = find(option::k2p(nv.first));
const SharedHandle<OptionHandler>& handler =
find(option::k2p(std::string(nv.first.first, nv.first.second)));
if(handler) {
handler->parse(option, nv.second);
handler->parse(option, std::string(nv.second.first, nv.second.second));
}
}
}

View File

@ -124,26 +124,29 @@ ParameterizedStringParser::createLoop(const std::string& src, int& offset)
}
loopStr.erase(colonIndex);
}
std::pair<std::string, std::string> range;
util::divide(range, loopStr, '-');
if(range.first.empty() || range.second.empty()) {
std::pair<Scip, Scip> range;
util::divide(range, loopStr.begin(), loopStr.end(), '-');
if(range.first.first == range.first.second ||
range.second.first == range.second.second) {
throw DL_ABORT_EX("Loop range missing.");
}
SharedHandle<NumberDecorator> nd;
unsigned int start;
unsigned int end;
if(util::isNumber(range.first) && util::isNumber(range.second)) {
nd.reset(new FixedWidthNumberDecorator(range.first.size()));
start = util::parseUInt(range.first.begin(), range.first.end());
end = util::parseUInt(range.second.begin(), range.second.end());
} else if(util::isLowercase(range.first) && util::isLowercase(range.second)) {
nd.reset(new AlphaNumberDecorator(range.first.size()));
start = util::alphaToNum(range.first);
end = util::alphaToNum(range.second);
} else if(util::isUppercase(range.first) && util::isUppercase(range.second)) {
nd.reset(new AlphaNumberDecorator(range.first.size(), true));
start = util::alphaToNum(range.first);
end = util::alphaToNum(range.second);
std::string rstart(range.first.first, range.first.second);
std::string rend(range.second.first, range.second.second);
if(util::isNumber(rstart) && util::isNumber(rend)) {
nd.reset(new FixedWidthNumberDecorator(rstart.size()));
start = util::parseUInt(rstart.begin(), rstart.end());
end = util::parseUInt(rend.begin(), rend.end());
} else if(util::isLowercase(rstart) && util::isLowercase(rend)) {
nd.reset(new AlphaNumberDecorator(rstart.size()));
start = util::alphaToNum(rstart);
end = util::alphaToNum(rend);
} else if(util::isUppercase(rstart) && util::isUppercase(rend)) {
nd.reset(new AlphaNumberDecorator(rstart.size(), true));
start = util::alphaToNum(rstart);
end = util::alphaToNum(rend);
} else {
throw DL_ABORT_EX("Invalid loop range.");
}

View File

@ -1126,11 +1126,14 @@ void changeOption
const SharedHandle<Option>& grOption = group->getOption();
grOption->merge(option);
if(option.defined(PREF_CHECKSUM)) {
std::pair<std::string, std::string> p;
util::divide(p, grOption->get(PREF_CHECKSUM), '=');
util::lowercase(p.first);
util::lowercase(p.second);
dctx->setDigest(p.first, util::fromHex(p.second));
const std::string& checksum = grOption->get(PREF_CHECKSUM);
std::pair<Scip, Scip> p;
util::divide(p, checksum.begin(), checksum.end(), '=');
std::string hashType(p.first.first, p.first.second);
std::string hexDigest(p.second.first, p.second.second);
util::lowercase(hashType);
util::lowercase(hexDigest);
dctx->setDigest(hashType, util::fromHex(hexDigest));
}
if(option.defined(PREF_SELECT_FILE)) {
SegList<int> sgl;

View File

@ -160,11 +160,10 @@ bool ServerStatMan::load(const std::string& filename)
std::map<std::string, std::string> m;
for(std::vector<std::string>::const_iterator i = items.begin(),
eoi = items.end(); i != eoi; ++i) {
std::pair<std::string, std::string> p;
util::divide(p, *i, '=');
p.first = util::strip(p.first);
p.second = util::strip(p.second);
m[p.first] = p.second;
std::pair<Scip, Scip> p;
util::divide(p, (*i).begin(), (*i).end(), '=');
m[std::string(p.first.first, p.first.second)] =
std::string(p.second.first, p.second.second);
}
if(m[S_HOST].empty() || m[S_PROTOCOL].empty()) {
continue;

View File

@ -129,11 +129,13 @@ SharedHandle<RequestGroup> createRequestGroup
#ifdef ENABLE_MESSAGE_DIGEST
const std::string& checksum = option->get(PREF_CHECKSUM);
if(!checksum.empty()) {
std::pair<std::string, std::string> p;
util::divide(p, checksum, '=');
util::lowercase(p.first);
util::lowercase(p.second);
dctx->setDigest(p.first, util::fromHex(p.second));
std::pair<Scip, Scip> p;
util::divide(p, checksum.begin(), checksum.end(), '=');
std::string hashType(p.first.first, p.first.second);
std::string hexDigest(p.second.first, p.second.second);
util::lowercase(hashType);
util::lowercase(hexDigest);
dctx->setDigest(hashType, hexDigest);
}
#endif // ENABLE_MESSAGE_DIGEST
rg->setDownloadContext(dctx);

View File

@ -191,24 +191,6 @@ std::string strip(const std::string& str, const std::string& chars)
return std::string(p.first, p.second);
}
void divide
(std::pair<std::string, std::string>& hp, const std::string& src, char delim)
{
std::string::const_iterator first = src.begin();
std::string::const_iterator last = src.end();
std::string::const_iterator dpos = std::find(first, last, delim);
if(dpos == last) {
hp.first = strip(src);
hp.second = A2STR::NIL;
} else {
std::pair<std::string::const_iterator,
std::string::const_iterator> p = stripIter(first, dpos);
hp.first.assign(p.first, p.second);
p = stripIter(dpos+1, last);
hp.second.assign(p.first, p.second);
}
}
std::string itos(int64_t value, bool comma)
{
bool flag = false;
@ -820,11 +802,9 @@ std::string getContentDispositionFilename(const std::string& header)
if(markeritr == param.end() || *markeritr != '=') {
continue;
}
std::pair<std::string, std::string> paramPair;
divide(paramPair, param, '=');
std::string value = paramPair.second;
std::string value(markeritr+1, param.end());
std::vector<std::string> extValues;
split(value, std::back_inserter(extValues), "'", false, true);
split(value, std::back_inserter(extValues), "'", true, true);
if(extValues.size() != 3) {
continue;
}
@ -877,17 +857,17 @@ std::string getContentDispositionFilename(const std::string& header)
}
} else {
for(; markeritr != param.end() && *markeritr == ' '; ++markeritr);
if(markeritr == param.end() || *markeritr != '=') {
if(markeritr == param.end() || markeritr+1 == param.end() ||
*markeritr != '=') {
continue;
}
std::pair<std::string, std::string> paramPair;
divide(paramPair, param, '=');
std::string value = paramPair.second;
if(value.empty()) {
Scip p = stripIter(markeritr+1, param.end());
if(p.first == p.second) {
continue;
}
std::string value(p.first, p.second);
std::string::iterator filenameLast;
if(*value.begin() == '\'' || *value.begin() == '"') {
if(value[0] == '\'' || value[0] == '"') {
char qc = *value.begin();
for(filenameLast = value.begin()+1;
filenameLast != value.end() && *filenameLast != qc;
@ -1248,14 +1228,14 @@ std::string htmlEscape(const std::string& src)
std::pair<size_t, std::string>
parseIndexPath(const std::string& line)
{
std::pair<std::string, std::string> p;
divide(p, line, '=');
size_t index = parseUInt(p.first.begin(), p.first.end());
if(p.second.empty()) {
std::pair<Scip, Scip> p;
divide(p, line.begin(), line.end(), '=');
size_t index = parseUInt(p.first.first, p.first.second);
if(p.second.first == p.second.second) {
throw DL_ABORT_EX(fmt("Path with index=%u is empty.",
static_cast<unsigned int>(index)));
}
return std::make_pair(index, p.second);
return std::make_pair(index, std::string(p.second.first, p.second.second));
}
std::vector<std::pair<size_t, std::string> > createIndexPaths(std::istream& i)

View File

@ -110,8 +110,22 @@ std::string nativeToUtf8(const std::string& src);
namespace util {
template<typename InputIterator>
void divide
(std::pair<std::string, std::string>& hp, const std::string& src, char delim);
(std::pair<Scip, Scip>& hp,
InputIterator first,
InputIterator last,
char delim)
{
InputIterator dpos = std::find(first, last, delim);
if(dpos == last) {
hp.first = stripIter(first, last);
hp.second.first = hp.second.second;
} else {
hp.first = stripIter(first, dpos);
hp.second = stripIter(dpos+1, last);
}
}
template<typename T>
std::string uitos(T value, bool comma = false)

View File

@ -212,22 +212,37 @@ void UtilTest::testStripIter()
}
void UtilTest::testDivide() {
std::pair<std::string, std::string> p1;
util::divide(p1, "name=value", '=');
CPPUNIT_ASSERT_EQUAL(std::string("name"), p1.first);
CPPUNIT_ASSERT_EQUAL(std::string("value"), p1.second);
util::divide(p1, " name = value ", '=');
CPPUNIT_ASSERT_EQUAL(std::string("name"), p1.first);
CPPUNIT_ASSERT_EQUAL(std::string("value"), p1.second);
util::divide(p1, "=value", '=');
CPPUNIT_ASSERT_EQUAL(std::string(""), p1.first);
CPPUNIT_ASSERT_EQUAL(std::string("value"), p1.second);
util::divide(p1, "name=", '=');
CPPUNIT_ASSERT_EQUAL(std::string("name"), p1.first);
CPPUNIT_ASSERT_EQUAL(std::string(""), p1.second);
util::divide(p1, "name", '=');
CPPUNIT_ASSERT_EQUAL(std::string("name"), p1.first);
CPPUNIT_ASSERT_EQUAL(std::string(""), p1.second);
std::pair<Scip, Scip> p1;
std::string s = "name=value";
util::divide(p1, s.begin(), s.end(), '=');
CPPUNIT_ASSERT_EQUAL(std::string("name"),
std::string(p1.first.first, p1.first.second));
CPPUNIT_ASSERT_EQUAL(std::string("value"),
std::string(p1.second.first, p1.second.second));
s = " name = value ";
util::divide(p1, s.begin(), s.end(), '=');
CPPUNIT_ASSERT_EQUAL(std::string("name"),
std::string(p1.first.first, p1.first.second));
CPPUNIT_ASSERT_EQUAL(std::string("value"),
std::string(p1.second.first, p1.second.second));
s = "=value";
util::divide(p1, s.begin(), s.end(), '=');
CPPUNIT_ASSERT_EQUAL(std::string(""),
std::string(p1.first.first, p1.first.second));
CPPUNIT_ASSERT_EQUAL(std::string("value"),
std::string(p1.second.first, p1.second.second));
s = "name=";
util::divide(p1, s.begin(), s.end(), '=');
CPPUNIT_ASSERT_EQUAL(std::string("name"),
std::string(p1.first.first, p1.first.second));
CPPUNIT_ASSERT_EQUAL(std::string(""),
std::string(p1.second.first, p1.second.second));
s = "name";
util::divide(p1, s.begin(), s.end(), '=');
CPPUNIT_ASSERT_EQUAL(std::string("name"),
std::string(p1.first.first, p1.first.second));
CPPUNIT_ASSERT_EQUAL(std::string(""),
std::string(p1.second.first, p1.second.second));
}
void UtilTest::testSplit() {
@ -407,6 +422,10 @@ void UtilTest::testGetContentDispositionFilename() {
std::string h3 = "attachment; filename=\"";
CPPUNIT_ASSERT_EQUAL(std::string(""), util::getContentDispositionFilename(h3));
std::string h3_2 = "attachment; filename= \" aria2.tar.bz2 \"";
CPPUNIT_ASSERT_EQUAL(std::string("aria2.tar.bz2"),
util::getContentDispositionFilename(h3_2));
std::string h4 = "attachment;";
CPPUNIT_ASSERT_EQUAL(std::string(""), util::getContentDispositionFilename(h4));