Added BufferedFile::getLine() to make reading one line more flexible.

Fixes bug#3495336
pull/13/head
Tatsuhiro Tsujikawa 2012-02-29 02:50:12 +09:00
parent c63a524a88
commit 037f1512db
6 changed files with 86 additions and 50 deletions

View File

@ -99,6 +99,28 @@ char* BufferedFile::getsn(char* s, int size)
return ptr; return ptr;
} }
std::string BufferedFile::getLine()
{
std::string res;
if(eof()) {
return res;
}
char buf[4096];
while(gets(buf, sizeof(buf))) {
size_t len = strlen(buf);
bool lineBreak = false;
if(buf[len-1] == '\n') {
--len;
lineBreak = true;
}
res.append(buf, len);
if(lineBreak) {
break;
}
}
return res;
}
int BufferedFile::close() int BufferedFile::close()
{ {
if(open_) { if(open_) {

View File

@ -52,8 +52,8 @@ public:
BufferedFile(const std::string& filename, const std::string& mode); BufferedFile(const std::string& filename, const std::string& mode);
BufferedFile(FILE* fp); BufferedFile(FILE* fp);
virtual ~BufferedFile(); virtual ~BufferedFile();
// Returns true if file is opened and both ferror and feof returns // Returns true if file is opened and ferror returns 0. Otherwise
// 0. Otherwise returns false. // returns false.
operator unspecified_bool_type() const; operator unspecified_bool_type() const;
// wrapper for fread. Using 1 for 2nd argument of fread. // wrapper for fread. Using 1 for 2nd argument of fread.
size_t read(void* ptr, size_t count); size_t read(void* ptr, size_t count);
@ -64,6 +64,8 @@ public:
char* gets(char* s, int size); char* gets(char* s, int size);
// wrapper for fgets, but trailing '\n' is replaced with '\0'. // wrapper for fgets, but trailing '\n' is replaced with '\0'.
char* getsn(char* s, int size); char* getsn(char* s, int size);
// Reads one line and returns it. The last '\n' is removed.
std::string getLine();
// wrapper for fclose // wrapper for fclose
int close(); int close();
// Return true if open_ && feof(fp_) != 0. Otherwise returns false. // Return true if open_ && feof(fp_) != 0. Otherwise returns false.

View File

@ -115,12 +115,16 @@ void Netrc::addAuthenticator(const SharedHandle<Authenticator>& authenticator)
namespace { namespace {
void skipMacdef(BufferedFile& fp) void skipMacdef(BufferedFile& fp)
{ {
char buf[4096]; std::string s;
while(1) { while(1) {
if(!fp.gets(buf, sizeof(buf))) { s = fp.getLine();
if(s.empty() || fp.eof()) {
break; break;
} }
if(buf[0] == '\n' || buf[0] == '\r') { if(!fp) {
throw DL_ABORT_EX("Netrc:I/O error.");
}
if(s[0] == '\n' || s[0] == '\r') {
break; break;
} }
} }
@ -144,18 +148,23 @@ void Netrc::parse(const std::string& path)
}; };
SharedHandle<Authenticator> authenticator; SharedHandle<Authenticator> authenticator;
STATE state = GET_TOKEN; STATE state = GET_TOKEN;
char buf[4096];
while(1) { while(1) {
if(!fp.getsn(buf, sizeof(buf))) { std::string line = fp.getLine();
break; if(line.empty()) {
if(fp.eof()) {
break;
} else if(!fp) {
throw DL_ABORT_EX("Netrc:I/O error.");
} else {
continue;
}
} }
size_t len = strlen(buf); if(line[0] == '#') {
if(len == 0 || buf[0] == '#') {
continue; continue;
} }
std::vector<Scip> tokens; std::vector<Scip> tokens;
util::splitIterM(&buf[0], &buf[len], std::back_inserter(tokens), " \t", util::splitIterM(line.begin(), line.end(), std::back_inserter(tokens),
true); " \t", true);
for(std::vector<Scip>::const_iterator iter = tokens.begin(), for(std::vector<Scip>::const_iterator iter = tokens.begin(),
eoi = tokens.end(); iter != eoi; ++iter) { eoi = tokens.end(); iter != eoi; ++iter) {
if(state == GET_TOKEN) { if(state == GET_TOKEN) {

View File

@ -55,10 +55,11 @@ NsCookieParser::~NsCookieParser() {}
namespace { namespace {
bool parseNsCookie bool parseNsCookie
(Cookie& cookie, const char* buf, size_t buflen, time_t creationTime) (Cookie& cookie, const std::string& cookieStr, time_t creationTime)
{ {
std::vector<Scip> vs; std::vector<Scip> vs;
util::splitIter(&buf[0], &buf[buflen], std::back_inserter(vs), '\t', true); util::splitIter(cookieStr.begin(), cookieStr.end(), std::back_inserter(vs),
'\t', true);
if(vs.size() < 6) { if(vs.size() < 6) {
return false; return false;
} }
@ -105,17 +106,22 @@ std::vector<Cookie> NsCookieParser::parse
throw DL_ABORT_EX(fmt("Failed to open file %s", filename.c_str())); throw DL_ABORT_EX(fmt("Failed to open file %s", filename.c_str()));
} }
std::vector<Cookie> cookies; std::vector<Cookie> cookies;
char buf[8192];
while(1) { while(1) {
if(!fp.getsn(buf, sizeof(buf))) { std::string line = fp.getLine();
break; if(line.empty()) {
if(fp.eof()) {
break;
} else if(!fp) {
throw DL_ABORT_EX("CookieParser:I/O error.");
} else {
continue;
}
} }
size_t len = strlen(buf); if(line[0] == '#') {
if(len == 0 || buf[0] == '#') {
continue; continue;
} }
Cookie c; Cookie c;
if(parseNsCookie(c, buf, len, creationTime)) { if(parseNsCookie(c, line, creationTime)) {
cookies.push_back(c); cookies.push_back(c);
} }
} }

View File

@ -137,26 +137,27 @@ bool ServerStatMan::load(const std::string& filename)
filename.c_str())); filename.c_str()));
return false; return false;
} }
char buf[4096];
while(1) { while(1) {
if(!fp.getsn(buf, sizeof(buf))) { std::string line = fp.getLine();
if(line.empty()) {
if(fp.eof()) { if(fp.eof()) {
break; break;
} else { } else if(!fp) {
A2_LOG_ERROR(fmt(MSG_READING_SERVER_STAT_FILE_FAILED, A2_LOG_ERROR(fmt(MSG_READING_SERVER_STAT_FILE_FAILED,
filename.c_str())); filename.c_str()));
return false; return false;
} else {
continue;
} }
} }
std::pair<std::string::const_iterator, std::pair<std::string::const_iterator,
std::string::const_iterator> p = std::string::const_iterator> p =
util::stripIter(&buf[0], &buf[strlen(buf)]); util::stripIter(line.begin(), line.end());
if(p.first == p.second) { if(p.first == p.second) {
continue; continue;
} }
std::string line(p.first, p.second);
std::vector<Scip> items; std::vector<Scip> items;
util::splitIter(line.begin(), line.end(), std::back_inserter(items), ','); util::splitIter(p.first, p.second, std::back_inserter(items), ',');
std::map<std::string, std::string> m; std::map<std::string, std::string> m;
for(std::vector<Scip>::const_iterator i = items.begin(), for(std::vector<Scip>::const_iterator i = items.begin(),
eoi = items.end(); i != eoi; ++i) { eoi = items.end(); i != eoi; ++i) {

View File

@ -55,14 +55,6 @@ UriListParser::~UriListParser() {}
void UriListParser::parseNext(std::vector<std::string>& uris, Option& op) void UriListParser::parseNext(std::vector<std::string>& uris, Option& op)
{ {
char buf[4096];
if(line_.empty()) {
if(!fp_.getsn(buf, sizeof(buf))) {
line_.clear();
return;
}
line_.assign(&buf[0], &buf[strlen(buf)]);
}
const SharedHandle<OptionParser>& optparser = OptionParser::getInstance(); const SharedHandle<OptionParser>& optparser = OptionParser::getInstance();
while(1) { while(1) {
if(!line_.empty() && line_[0] != '#') { if(!line_.empty() && line_[0] != '#') {
@ -71,31 +63,35 @@ void UriListParser::parseNext(std::vector<std::string>& uris, Option& op)
// Read options // Read options
std::stringstream ss; std::stringstream ss;
while(1) { while(1) {
if(!fp_.getsn(buf, sizeof(buf))) { line_ = fp_.getLine();
line_.clear();
break;
}
line_.assign(&buf[0], &buf[strlen(buf)]);
if(line_.empty()) { if(line_.empty()) {
if(fp_.eof()) {
break;
} else if(!fp_) {
throw DL_ABORT_EX("UriListParser:I/O error.");
} else {
continue;
}
}
if(line_[0] == ' ' || line_[0] == '\t') {
ss << line_ << "\n";
} else if(line_[0] == '#') {
continue; continue;
} else { } else {
if(line_[0] == ' ' || line_[0] == '\t') { break;
ss << line_ << "\n";
} else if(line_[0] == '#') {
continue;
} else {
break;
}
} }
} }
optparser->parse(op, ss); optparser->parse(op, ss);
return; return;
} }
if(!fp_.getsn(buf, sizeof(buf))) { line_ = fp_.getLine();
line_.clear(); if(line_.empty()) {
return; if(fp_.eof()) {
return;
} else if(!fp_) {
throw DL_ABORT_EX("UriListParser:I/O error.");
}
} }
line_.assign(&buf[0], &buf[strlen(buf)]);
} }
} }