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

View File

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

View File

@ -249,9 +249,10 @@ std::string HttpResponse::getContentType() const
if(!httpHeader_) { if(!httpHeader_) {
return A2STR::NIL; return A2STR::NIL;
} else { } else {
std::pair<std::string, std::string> p; const std::string& ctype = httpHeader_->getFirst(HttpHeader::CONTENT_TYPE);
util::divide(p, httpHeader_->getFirst(HttpHeader::CONTENT_TYPE), ';'); std::string::const_iterator i = std::find(ctype.begin(), ctype.end(), ';');
return p.first; 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; return true;
} }
std::string authHeader = lastRequestHeader_->getFirst("Authorization"); const std::string& authHeader = lastRequestHeader_->getFirst("Authorization");
if(authHeader.empty()) { if(authHeader.empty()) {
return false; return false;
} }
std::pair<std::string, std::string> p; std::pair<Scip, Scip> p;
util::divide(p, authHeader, ' '); util::divide(p, authHeader.begin(), authHeader.end(), ' ');
if(p.first != "Basic") { 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; return false;
} }
std::string userpass = Base64::decode(p.second); std::string userpass = Base64::decode(std::string(p.second.first,
std::pair<std::string, std::string> userpassPair; p.second.second));
util::divide(userpassPair, userpass, ':'); util::divide(p, userpass.begin(), userpass.end(), ':');
return username_ == userpassPair.first && password_ == userpassPair.second; 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 void HttpServer::setUsernamePassword

View File

@ -365,11 +365,13 @@ ChecksumOptionHandler::~ChecksumOptionHandler() {}
void ChecksumOptionHandler::parseArg(Option& option, const std::string& optarg) void ChecksumOptionHandler::parseArg(Option& option, const std::string& optarg)
{ {
std::pair<std::string, std::string> p; std::pair<Scip, Scip> p;
util::divide(p, optarg, '='); util::divide(p, optarg.begin(), optarg.end(), '=');
util::lowercase(p.first); std::string hashType(p.first.first, p.first.second);
util::lowercase(p.second); std::string hexDigest(p.second.first, p.second.second);
if(!MessageDigest::isValidHash(p.first, p.second)) { util::lowercase(hashType);
util::lowercase(hexDigest);
if(!MessageDigest::isValidHash(hashType, hexDigest)) {
throw DL_ABORT_EX(_("Unrecognized checksum")); throw DL_ABORT_EX(_("Unrecognized checksum"));
} }
option.put(pref_, optarg); 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)) { if(util::startsWith(line, A2STR::SHARP_C)) {
continue; continue;
} }
std::pair<std::string, std::string> nv; std::pair<Scip, Scip> nv;
util::divide(nv, line, '='); util::divide(nv, line.begin(), line.end(), '=');
if(nv.first.empty()) { if(nv.first.first == nv.first.second) {
continue; 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) { 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); loopStr.erase(colonIndex);
} }
std::pair<std::string, std::string> range; std::pair<Scip, Scip> range;
util::divide(range, loopStr, '-'); util::divide(range, loopStr.begin(), loopStr.end(), '-');
if(range.first.empty() || range.second.empty()) { if(range.first.first == range.first.second ||
range.second.first == range.second.second) {
throw DL_ABORT_EX("Loop range missing."); throw DL_ABORT_EX("Loop range missing.");
} }
SharedHandle<NumberDecorator> nd; SharedHandle<NumberDecorator> nd;
unsigned int start; unsigned int start;
unsigned int end; unsigned int end;
if(util::isNumber(range.first) && util::isNumber(range.second)) { std::string rstart(range.first.first, range.first.second);
nd.reset(new FixedWidthNumberDecorator(range.first.size())); std::string rend(range.second.first, range.second.second);
start = util::parseUInt(range.first.begin(), range.first.end()); if(util::isNumber(rstart) && util::isNumber(rend)) {
end = util::parseUInt(range.second.begin(), range.second.end()); nd.reset(new FixedWidthNumberDecorator(rstart.size()));
} else if(util::isLowercase(range.first) && util::isLowercase(range.second)) { start = util::parseUInt(rstart.begin(), rstart.end());
nd.reset(new AlphaNumberDecorator(range.first.size())); end = util::parseUInt(rend.begin(), rend.end());
start = util::alphaToNum(range.first); } else if(util::isLowercase(rstart) && util::isLowercase(rend)) {
end = util::alphaToNum(range.second); nd.reset(new AlphaNumberDecorator(rstart.size()));
} else if(util::isUppercase(range.first) && util::isUppercase(range.second)) { start = util::alphaToNum(rstart);
nd.reset(new AlphaNumberDecorator(range.first.size(), true)); end = util::alphaToNum(rend);
start = util::alphaToNum(range.first); } else if(util::isUppercase(rstart) && util::isUppercase(rend)) {
end = util::alphaToNum(range.second); nd.reset(new AlphaNumberDecorator(rstart.size(), true));
start = util::alphaToNum(rstart);
end = util::alphaToNum(rend);
} else { } else {
throw DL_ABORT_EX("Invalid loop range."); throw DL_ABORT_EX("Invalid loop range.");
} }

View File

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

View File

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

View File

@ -129,11 +129,13 @@ SharedHandle<RequestGroup> createRequestGroup
#ifdef ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST
const std::string& checksum = option->get(PREF_CHECKSUM); const std::string& checksum = option->get(PREF_CHECKSUM);
if(!checksum.empty()) { if(!checksum.empty()) {
std::pair<std::string, std::string> p; std::pair<Scip, Scip> p;
util::divide(p, checksum, '='); util::divide(p, checksum.begin(), checksum.end(), '=');
util::lowercase(p.first); std::string hashType(p.first.first, p.first.second);
util::lowercase(p.second); std::string hexDigest(p.second.first, p.second.second);
dctx->setDigest(p.first, util::fromHex(p.second)); util::lowercase(hashType);
util::lowercase(hexDigest);
dctx->setDigest(hashType, hexDigest);
} }
#endif // ENABLE_MESSAGE_DIGEST #endif // ENABLE_MESSAGE_DIGEST
rg->setDownloadContext(dctx); 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); 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) std::string itos(int64_t value, bool comma)
{ {
bool flag = false; bool flag = false;
@ -820,11 +802,9 @@ std::string getContentDispositionFilename(const std::string& header)
if(markeritr == param.end() || *markeritr != '=') { if(markeritr == param.end() || *markeritr != '=') {
continue; continue;
} }
std::pair<std::string, std::string> paramPair; std::string value(markeritr+1, param.end());
divide(paramPair, param, '=');
std::string value = paramPair.second;
std::vector<std::string> extValues; 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) { if(extValues.size() != 3) {
continue; continue;
} }
@ -877,17 +857,17 @@ std::string getContentDispositionFilename(const std::string& header)
} }
} else { } else {
for(; markeritr != param.end() && *markeritr == ' '; ++markeritr); for(; markeritr != param.end() && *markeritr == ' '; ++markeritr);
if(markeritr == param.end() || *markeritr != '=') { if(markeritr == param.end() || markeritr+1 == param.end() ||
*markeritr != '=') {
continue; continue;
} }
std::pair<std::string, std::string> paramPair; Scip p = stripIter(markeritr+1, param.end());
divide(paramPair, param, '='); if(p.first == p.second) {
std::string value = paramPair.second;
if(value.empty()) {
continue; continue;
} }
std::string value(p.first, p.second);
std::string::iterator filenameLast; std::string::iterator filenameLast;
if(*value.begin() == '\'' || *value.begin() == '"') { if(value[0] == '\'' || value[0] == '"') {
char qc = *value.begin(); char qc = *value.begin();
for(filenameLast = value.begin()+1; for(filenameLast = value.begin()+1;
filenameLast != value.end() && *filenameLast != qc; filenameLast != value.end() && *filenameLast != qc;
@ -1248,14 +1228,14 @@ std::string htmlEscape(const std::string& src)
std::pair<size_t, std::string> std::pair<size_t, std::string>
parseIndexPath(const std::string& line) parseIndexPath(const std::string& line)
{ {
std::pair<std::string, std::string> p; std::pair<Scip, Scip> p;
divide(p, line, '='); divide(p, line.begin(), line.end(), '=');
size_t index = parseUInt(p.first.begin(), p.first.end()); size_t index = parseUInt(p.first.first, p.first.second);
if(p.second.empty()) { if(p.second.first == p.second.second) {
throw DL_ABORT_EX(fmt("Path with index=%u is empty.", throw DL_ABORT_EX(fmt("Path with index=%u is empty.",
static_cast<unsigned int>(index))); 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) 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 { namespace util {
template<typename InputIterator>
void divide 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> template<typename T>
std::string uitos(T value, bool comma = false) std::string uitos(T value, bool comma = false)

View File

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