2008-04-26 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Added StringFormat class, which internally calls vasprintf.
	operator<< is defined for this class, so it can be used with iostream
	classes nicely. SimpleLogger and following functions are rewritten
	using StringFormat class.
	Besides, now Logger class's methods are non-const, many classes
	that has a const Logger* as a member variable are modified to remove
	const qualifier from the variable declaration.
	* src/HelpItemFactory.cc
	* src/Request.cc
	* src/SimpleLogger.cc
	* src/StringFormat.cc
	* src/StringFormat.h
	* src/Util.cc
	* src/option_processing.cc
	* src/version_usage.cc
	* test/StringFormatTest.cc
	* src/*.h: The classes that has const Logger* as a member variable.
pull/1/head
Tatsuhiro Tsujikawa 2008-04-26 05:58:49 +00:00
parent 0f92203ffe
commit 90d5b5c0a2
57 changed files with 341 additions and 146 deletions

View File

@ -1,3 +1,23 @@
2008-04-26 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added StringFormat class, which internally calls vasprintf.
operator<< is defined for this class, so it can be used with iostream
classes nicely. SimpleLogger and following functions are rewritten
using StringFormat class.
Besides, now Logger class's methods are non-const, many classes
that has a const Logger* as a member variable are modified to remove
const qualifier from the variable declaration.
* src/HelpItemFactory.cc
* src/Request.cc
* src/SimpleLogger.cc
* src/StringFormat.cc
* src/StringFormat.h
* src/Util.cc
* src/option_processing.cc
* src/version_usage.cc
* test/StringFormatTest.cc
* src/*.h: The classes that has const Logger* as a member variable.
2008-04-26 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Log error in AccRequestGroup when reading BitTorrent/Metalink file is

View File

@ -76,7 +76,7 @@ protected:
std::deque<SharedHandle<BtEventListener> > listeners;
const Logger* logger;
Logger* logger;
public:
AbstractBtMessage();

View File

@ -46,7 +46,7 @@ class AbstractDiskWriter : public DiskWriter {
protected:
std::string filename;
int fd;
const Logger* logger;
Logger* logger;
void createFile(const std::string& filename, int addFlags = 0);

View File

@ -49,7 +49,7 @@ private:
WeakHandle<RequestGroup> _dependant;
SharedHandle<RequestGroup> _dependee;
const Option* _option;
const Logger* _logger;
Logger* _logger;
public:
BtDependency(const WeakHandle<RequestGroup>& dependant,
const SharedHandle<RequestGroup>& dependee,

View File

@ -51,7 +51,7 @@ private:
Time _lastRound;
const Logger* _logger;
Logger* _logger;
void plannedOptimisticUnchoke(std::deque<Peer*>& peers);

View File

@ -54,7 +54,7 @@ private:
Time _lastRound;
const Logger* _logger;
Logger* _logger;
void unchoke(std::deque<Peer*>& peers);
public:

View File

@ -48,7 +48,7 @@ class Command;
class BtSetup {
private:
const Logger* _logger;
Logger* _logger;
public:
BtSetup();

View File

@ -60,7 +60,7 @@ private:
STATUS status;
protected:
int32_t cuid;
const Logger* logger;
Logger* logger;
public:
Command(int32_t cuid);

View File

@ -54,7 +54,7 @@ class DHTAbstractTask:public DHTTask {
protected:
bool _finished;
const Logger* _logger;
Logger* _logger;
SharedHandle<DHTNode> _localNode;

View File

@ -67,7 +67,7 @@ private:
Time _lastUpdated;
const Logger* _logger;
Logger* _logger;
public:
DHTBucket(const SharedHandle<DHTNode>& localNode);

View File

@ -48,7 +48,7 @@ class DHTConnectionImpl:public DHTConnection {
private:
SharedHandle<SocketCore> _socket;
const Logger* _logger;
Logger* _logger;
public:
DHTConnectionImpl();

View File

@ -50,7 +50,7 @@ private:
std::deque<SharedHandle<DHTMessageEntry> > _messageQueue;
const Logger* _logger;
Logger* _logger;
void sendMessage(const SharedHandle<DHTMessageEntry>& msg);
public:

View File

@ -63,7 +63,7 @@ private:
WeakHandle<DHTTokenTracker> _tokenTracker;
const Logger* _logger;
Logger* _logger;
// search node in routingTable. If it is not found, create new one.
SharedHandle<DHTNode> getRemoteNode(const unsigned char* id, const std::string& ipaddr, uint16_t port) const;

View File

@ -58,7 +58,7 @@ private:
SharedHandle<DHTRoutingTable> _routingTable;
const Logger* _logger;
Logger* _logger;
SharedHandle<DHTMessage>
handleUnknownMessage(const unsigned char* data, size_t length,

View File

@ -59,7 +59,7 @@ private:
SharedHandle<DHTMessageFactory> _factory;
const Logger* _logger;
Logger* _logger;
public:
DHTMessageTracker();

View File

@ -58,7 +58,7 @@ private:
SharedHandle<DHTTaskFactory> _taskFactory;
const Logger* _logger;
Logger* _logger;
public:
DHTPeerAnnounceStorage();

View File

@ -61,7 +61,7 @@ private:
SharedHandle<DHTTaskFactory> _taskFactory;
const Logger* _logger;
Logger* _logger;
bool addNode(const SharedHandle<DHTNode>& node, bool good);
public:

View File

@ -48,7 +48,7 @@ class DHTSetup {
private:
static size_t _initialized;
const Logger* _logger;
Logger* _logger;
public:
DHTSetup();

View File

@ -59,7 +59,7 @@ private:
WeakHandle<DHTTaskQueue> _taskQueue;
const Logger* _logger;
Logger* _logger;
void setCommonProperty(const SharedHandle<DHTAbstractTask>& task);
public:

View File

@ -69,7 +69,7 @@ private:
RequestGroup* _ownerRequestGroup;
const Logger* _logger;
Logger* _logger;
void clear();
void extractPieceHash(const unsigned char* hashData,

View File

@ -98,7 +98,7 @@ private:
WeakHandle<DHTNode> _localNode;
const Logger* logger;
Logger* logger;
size_t allowedFastSetSize;
Time haveCheckPoint;
Time keepAliveCheckPoint;

View File

@ -61,7 +61,7 @@ private:
SharedHandle<Peer> peer;
unsigned int maxUploadSpeedLimit;
time_t requestTimeout;
const Logger* logger;
Logger* logger;
public:
DefaultBtMessageDispatcher();

View File

@ -55,7 +55,7 @@ private:
WeakHandle<PeerConnection> peerConnection;
WeakHandle<BtMessageDispatcher> dispatcher;
WeakHandle<BtMessageFactory> messageFactory;
const Logger* logger;
Logger* logger;
void sendHandshake();
public:

View File

@ -49,7 +49,7 @@ private:
SharedHandle<DownloadContext> _dctx;
SharedHandle<PieceStorage> _pieceStorage;
const Option* _option;
const Logger* _logger;
Logger* _logger;
std::string _filename;
bool isTorrentDownload();

View File

@ -49,7 +49,7 @@ private:
SharedHandle<Peer> _peer;
const Logger* _logger;
Logger* _logger;
public:
DefaultExtensionMessageFactory();

View File

@ -49,7 +49,7 @@ class DiskAdaptor:public BinaryStream {
protected:
std::string storeDir;
std::deque<SharedHandle<FileEntry> > fileEntries;
const Logger* logger;
Logger* logger;
public:
DiskAdaptor();
virtual ~DiskAdaptor();

View File

@ -99,7 +99,7 @@ private:
fd_set wfdset;
int fdmax;
const Logger* logger;
Logger* logger;
SharedHandle<StatCalc> _statCalc;

View File

@ -48,7 +48,7 @@ class DownloadEngine;
class DownloadEngineFactory {
private:
const Logger* _logger;
Logger* _logger;
public:
DownloadEngineFactory();

View File

@ -51,7 +51,7 @@ class DownloadHandler
protected:
SharedHandle<RequestGroupCriteria> _criteria;
const Logger* _logger;
Logger* _logger;
public:
DownloadHandler();

View File

@ -54,7 +54,7 @@ private:
SharedHandle<SocketCore> socket;
SharedHandle<Request> req;
const Option* option;
const Logger* logger;
Logger* logger;
std::string strbuf;

View File

@ -59,7 +59,7 @@ private:
SharedHandle<Peer> _peer;
const Logger* _logger;
Logger* _logger;
public:
HandshakeExtensionMessage();

View File

@ -40,6 +40,7 @@
#include "a2io.h"
#include "help_tags.h"
#include "Option.h"
#include "StringFormat.h"
namespace aria2 {
@ -459,9 +460,8 @@ TagContainerHandle HelpItemFactory::createHelpItems(const Option* op)
}
{
HelpItemHandle item(new HelpItem("help", TEXT_HELP, TAG_BASIC));
char buf[64];
snprintf(buf, sizeof(buf), "%s,%s,%s,%s,%s,%s,all", TAG_BASIC, TAG_ADVANCED, TAG_HTTP, TAG_FTP, TAG_METALINK, TAG_BITTORRENT);
item->setAvailableValues(buf);
item->setAvailableValues
(StringFormat("%s,%s,%s,%s,%s,%s,all", TAG_BASIC, TAG_ADVANCED, TAG_HTTP, TAG_FTP, TAG_METALINK, TAG_BITTORRENT).toString());
item->addTag(TAG_BASIC);
tc->addItem(item);
}

View File

@ -72,7 +72,7 @@ private:
int32_t cuid;
SharedHandle<SocketCore> socket;
const Option* option;
const Logger* logger;
Logger* logger;
HttpRequestEntries outstandingHttpRequests;

View File

@ -51,7 +51,7 @@ private:
int32_t cuid;
SharedHandle<HttpRequest> httpRequest;
SharedHandle<HttpHeader> httpHeader;
const Logger* logger;
Logger* logger;
public:
HttpResponse();

View File

@ -55,7 +55,7 @@ private:
SharedHandle<MessageDigestContext> _ctx;
const Logger* _logger;
Logger* _logger;
unsigned char* _buffer;

View File

@ -52,7 +52,7 @@ private:
SharedHandle<PieceStorage> _pieceStorage;
BitfieldMan* _bitfield;
size_t _currentIndex;
const Logger* _logger;
Logger* _logger;
SharedHandle<MessageDigestContext> _ctx;
unsigned char* _buffer;

View File

@ -44,16 +44,16 @@ class Exception;
class Logger {
public:
virtual ~Logger() {}
virtual void debug(const char* msg, ...) const = 0;
virtual void debug(const char* msg, Exception* ex, ...) const = 0;
virtual void info(const char* msg, ...) const = 0;
virtual void info(const char* msg, Exception* ex, ...) const = 0;
virtual void notice(const char* msg, ...) const = 0;
virtual void notice(const char* msg, Exception* ex, ...) const = 0;
virtual void warn(const char* msg, ...) const = 0;
virtual void warn(const char* msg, Exception* ex, ...) const = 0;
virtual void error(const char* msg, ...) const = 0;
virtual void error(const char* msg, Exception* ex, ...) const = 0;
virtual void debug(const char* msg, ...) = 0;
virtual void debug(const char* msg, Exception* ex, ...) = 0;
virtual void info(const char* msg, ...) = 0;
virtual void info(const char* msg, Exception* ex, ...) = 0;
virtual void notice(const char* msg, ...) = 0;
virtual void notice(const char* msg, Exception* ex, ...) = 0;
virtual void warn(const char* msg, ...) = 0;
virtual void warn(const char* msg, Exception* ex, ...) = 0;
virtual void error(const char* msg, ...) = 0;
virtual void error(const char* msg, Exception* ex, ...) = 0;
enum LEVEL {
DEBUG = 1 << 0,

View File

@ -78,7 +78,7 @@ private:
int32_t _cuid;
SharedHandle<SocketCore> _socket;
const Option* _option;
const Logger* _logger;
Logger* _logger;
unsigned char _rbuf[MAX_BUFFER_LENGTH];
size_t _rbufLength;

View File

@ -182,7 +182,8 @@ SRCS = Socket.h\
prefs.h\
usage_text.h\
ProtocolDetector.cc ProtocolDetector.h\
NullStatCalc.h
NullStatCalc.h\
StringFormat.cc StringFormat.h
if ENABLE_MESSAGE_DIGEST
SRCS += IteratableChunkChecksumValidator.cc IteratableChunkChecksumValidator.h\

View File

@ -404,7 +404,8 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \
TrueRequestGroupCriteria.h a2algo.h a2functional.h a2io.h \
a2netcompat.h a2time.h array_fun.h help_tags.h prefs.h \
usage_text.h ProtocolDetector.cc ProtocolDetector.h \
NullStatCalc.h IteratableChunkChecksumValidator.cc \
NullStatCalc.h StringFormat.cc StringFormat.h \
IteratableChunkChecksumValidator.cc \
IteratableChunkChecksumValidator.h \
IteratableChecksumValidator.cc IteratableChecksumValidator.h \
CheckIntegrityCommand.cc CheckIntegrityCommand.h \
@ -780,11 +781,11 @@ am__objects_14 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \
HelpItem.$(OBJEXT) TaggedItem.$(OBJEXT) TagContainer.$(OBJEXT) \
HelpItemFactory.$(OBJEXT) SingleFileDownloadContext.$(OBJEXT) \
TimedHaltCommand.$(OBJEXT) ProtocolDetector.$(OBJEXT) \
$(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
$(am__objects_10) $(am__objects_11) $(am__objects_12) \
$(am__objects_13)
StringFormat.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
$(am__objects_9) $(am__objects_10) $(am__objects_11) \
$(am__objects_12) $(am__objects_13)
am_libaria2c_a_OBJECTS = $(am__objects_14)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
@ -1119,11 +1120,11 @@ SRCS = Socket.h SocketCore.cc SocketCore.h BinaryStream.h Command.cc \
TrueRequestGroupCriteria.h a2algo.h a2functional.h a2io.h \
a2netcompat.h a2time.h array_fun.h help_tags.h prefs.h \
usage_text.h ProtocolDetector.cc ProtocolDetector.h \
NullStatCalc.h $(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_4) $(am__append_5) $(am__append_6) \
$(am__append_7) $(am__append_8) $(am__append_9) \
$(am__append_10) $(am__append_11) $(am__append_12) \
$(am__append_13)
NullStatCalc.h StringFormat.cc StringFormat.h $(am__append_1) \
$(am__append_2) $(am__append_3) $(am__append_4) \
$(am__append_5) $(am__append_6) $(am__append_7) \
$(am__append_8) $(am__append_9) $(am__append_10) \
$(am__append_11) $(am__append_12) $(am__append_13)
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@ -1459,6 +1460,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpeedCalc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamCheckIntegrityEntry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamFileAllocationEntry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringFormat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TagContainer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TaggedItem.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeA2.Po@am__quote@

View File

@ -52,7 +52,7 @@ class Metalink2RequestGroup {
private:
const Option* _option;
const Logger* _logger;
Logger* _logger;
std::deque<SharedHandle<RequestGroup> >
createRequestGroup(std::deque<SharedHandle<MetalinkEntry> > entries);

View File

@ -57,7 +57,7 @@ private:
std::ostream& _summaryOut;
const Logger* _logger;
Logger* _logger;
void printMessageForContinue();

View File

@ -56,7 +56,7 @@ private:
int32_t cuid;
SharedHandle<SocketCore> socket;
const Option* option;
const Logger* logger;
Logger* logger;
unsigned char resbuf[MAX_PAYLOAD_LEN];
size_t resbufLength;

View File

@ -38,6 +38,7 @@
#include "CookieBoxFactory.h"
#include "CookieBox.h"
#include "RecoverableException.h"
#include "StringFormat.h"
#include <utility>
namespace aria2 {
@ -180,10 +181,7 @@ std::string Request::urlencode(const std::string& src) const
result.replace(index, 1, "%25");
}
} else {
char temp[4];
sprintf(temp, "%%%02x", c);
temp[3] = '\0';
result.replace(index, 1, temp);
result.replace(index, 1, StringFormat("%%%02x", c).toString());
}
}
}

View File

@ -112,7 +112,7 @@ private:
const Option* _option;
const Logger* _logger;
Logger* _logger;
void validateFilename(const std::string& expectedFilename,
const std::string& actualFilename) const;

View File

@ -55,7 +55,7 @@ private:
std::deque<SharedHandle<RequestGroup> > _requestGroups;
std::deque<SharedHandle<RequestGroup> > _reservedGroups;
std::deque<SharedHandle<DownloadResult> > _downloadResults;
const Logger* _logger;
Logger* _logger;
unsigned int _maxSimultaneousDownloads;
int32_t _gidCounter;

View File

@ -69,7 +69,7 @@ class SegmentMan {
private:
const Option* _option;
const Logger* logger;
Logger* logger;
SharedHandle<DownloadContext> _downloadContext;

View File

@ -38,8 +38,11 @@
#include "message.h"
#include "a2io.h"
#include "a2time.h"
#include "StringFormat.h"
#include <cerrno>
#include <cstring>
#include <iostream>
#include <cstdlib>
namespace aria2 {
@ -63,22 +66,22 @@ va_start(ap, EX);\
writeFile(Logger::LEVEL, MSG, ap, EX);\
va_end(ap);
SimpleLogger::SimpleLogger(FILE* logfile):file(logfile), stdoutField(0) {}
SimpleLogger::SimpleLogger():stdoutField(0) {}
SimpleLogger::~SimpleLogger() {
closeFile();
}
void SimpleLogger::openFile(const std::string& filename) {
file = fopen(filename.c_str(), "ab");
if(file == NULL) {
file.open(filename.c_str(), std::ios::app|std::ios::binary);
if(!file) {
throw new DlAbortEx(EX_FILE_OPEN, filename.c_str(), strerror(errno));
}
}
void SimpleLogger::closeFile() {
if(file != NULL) {
fclose(file);
if(file.is_open()) {
file.close();
}
}
@ -90,13 +93,15 @@ void SimpleLogger::setStdout(Logger::LEVEL level, bool enabled) {
}
}
void SimpleLogger::writeHeader(FILE* file,
const std::string& date, const std::string& level) const
void SimpleLogger::writeHeader(std::ostream& o, const std::string& date,
const std::string& level)
{
fprintf(file, "%s %s - ", date.c_str(), level.c_str());
o << StringFormat("%s %s - ", date.c_str(), level.c_str());
}
void SimpleLogger::writeLog(FILE* file, Logger::LEVEL level, const char* msg, va_list ap, Exception* e, bool printHeader) const
void SimpleLogger::writeLog(std::ostream& o, Logger::LEVEL level,
const char* msg, va_list ap, Exception* e,
bool printHeader)
{
va_list apCopy;
va_copy(apCopy, ap);
@ -126,65 +131,74 @@ void SimpleLogger::writeLog(FILE* file, Logger::LEVEL level, const char* msg, va
// TODO a quick hack not to print header in console
if(printHeader) {
writeHeader(file, datestr, levelStr);
writeHeader(o, datestr, levelStr);
}
{
char* res;
if(vasprintf(&res, std::string(Util::replace(msg, "\r", "")+"\n").c_str(), apCopy) == -1) {
o << "SimpleLogger error, cannot allocate memory.\n";
} else {
o << res;
free(res);
}
}
vfprintf(file, std::string(Util::replace(msg, "\r", "")+"\n").c_str(), apCopy);
for(Exception* nestedEx = e; nestedEx; nestedEx = nestedEx->getCause()) {
// TODO a quick hack not to print header in console
if(printHeader) {
writeHeader(file, datestr, levelStr);
writeHeader(o, datestr, levelStr);
}
fprintf(file, "exception: %s\n", Util::replace(nestedEx->getMsg(), "\r", "").c_str());
o << StringFormat("exception: %s\n", Util::replace(nestedEx->getMsg(), "\r", "").c_str());
}
fflush(file);
o << std::flush;
va_end(apCopy);
}
void SimpleLogger::writeFile(Logger::LEVEL level, const char* msg, va_list ap, Exception* e) const {
void SimpleLogger::writeFile(Logger::LEVEL level, const char* msg, va_list ap, Exception* e)
{
writeLog(file, level, msg, ap, e);
if(stdoutField&level) {
fprintf(stdout, "\n");
writeLog(stdout, level, msg, ap, e);
std::cout << "\n";
writeLog(std::cout, level, msg, ap, e);
}
}
void SimpleLogger::debug(const char* msg, ...) const {
void SimpleLogger::debug(const char* msg, ...) {
WRITE_LOG(DEBUG, msg);
}
void SimpleLogger::debug(const char* msg, Exception* e, ...) const {
void SimpleLogger::debug(const char* msg, Exception* e, ...) {
WRITE_LOG_EX(DEBUG, msg, e);
}
void SimpleLogger::info(const char* msg, ...) const {
void SimpleLogger::info(const char* msg, ...) {
WRITE_LOG(INFO, msg);
}
void SimpleLogger::info(const char* msg, Exception* e, ...) const {
void SimpleLogger::info(const char* msg, Exception* e, ...) {
WRITE_LOG_EX(INFO, msg, e);
}
void SimpleLogger::notice(const char* msg, ...) const {
void SimpleLogger::notice(const char* msg, ...) {
WRITE_LOG(NOTICE, msg);
}
void SimpleLogger::notice(const char* msg, Exception* e, ...) const {
void SimpleLogger::notice(const char* msg, Exception* e, ...) {
WRITE_LOG_EX(INFO, msg, e);
}
void SimpleLogger::warn(const char* msg, ...) const {
void SimpleLogger::warn(const char* msg, ...) {
WRITE_LOG(WARN, msg);
}
void SimpleLogger::warn(const char* msg, Exception* e, ...) const {
void SimpleLogger::warn(const char* msg, Exception* e, ...) {
WRITE_LOG_EX(WARN, msg, e);
}
void SimpleLogger::error(const char* msg, ...) const {
void SimpleLogger::error(const char* msg, ...) {
WRITE_LOG(ERROR, msg);
}
void SimpleLogger::error(const char* msg, Exception* e, ...) const {
void SimpleLogger::error(const char* msg, Exception* e, ...) {
WRITE_LOG_EX(ERROR, msg, e);
}

View File

@ -36,38 +36,39 @@
#define _D_SIMPLE_LOGGER_H_
#include "Logger.h"
#include <cstdio>
#include <cstdarg>
#include <string>
#include <fstream>
namespace aria2 {
class SimpleLogger:public Logger {
private:
void writeFile(Logger::LEVEL level, const char* msg, va_list ap, Exception* e = 0) const;
void writeHeader(FILE* file,
const std::string& date, const std::string& level) const;
void writeLog(FILE* file, Logger::LEVEL level,
void writeFile(Logger::LEVEL level, const char* msg, va_list ap, Exception* e = 0);
void writeHeader(std::ostream& out,
const std::string& date, const std::string& level);
void writeLog(std::ostream& out, Logger::LEVEL level,
const char* msg, va_list ap,
Exception* e = 0, bool printHeader = true) const;
FILE* file;
Exception* e = 0, bool printHeader = true);
std::ofstream file;
int stdoutField;
public:
SimpleLogger(FILE* logfile = 0);
SimpleLogger();
~SimpleLogger();
void openFile(const std::string& filename);
void closeFile();
virtual void debug(const char* msg, ...) const;
virtual void debug(const char* msg, Exception* ex, ...) const;
virtual void info(const char* msg, ...) const;
virtual void info(const char* msg, Exception* ex, ...) const;
virtual void notice(const char* msg, ...) const;
virtual void notice(const char* msg, Exception* ex, ...) const;
virtual void warn(const char* msg, ...) const;
virtual void warn(const char* msg, Exception* ex, ...) const;
virtual void error(const char* msg, ...) const;
virtual void error(const char* msg, Exception* ex, ...) const;
virtual void debug(const char* msg, ...);
virtual void debug(const char* msg, Exception* ex, ...);
virtual void info(const char* msg, ...);
virtual void info(const char* msg, Exception* ex, ...);
virtual void notice(const char* msg, ...);
virtual void notice(const char* msg, Exception* ex, ...);
virtual void warn(const char* msg, ...);
virtual void warn(const char* msg, Exception* ex, ...);
virtual void error(const char* msg, ...);
virtual void error(const char* msg, Exception* ex, ...);
void setStdout(Logger::LEVEL level, bool enabled);
};

67
src/StringFormat.cc Normal file
View File

@ -0,0 +1,67 @@
/* <!-- 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 "StringFormat.h"
#include <ostream>
#include <cstring>
#include <cstdio>
#include <cstdarg>
#include <cstdlib>
namespace aria2 {
StringFormat::StringFormat(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
char* strp;
if(vasprintf(&strp, fmt, ap) != -1) {
_msg.assign(&strp[0], &strp[strlen(strp)]);
free(strp);
}
va_end(ap);
}
const std::string& StringFormat::toString() const
{
return _msg;
}
std::ostream& operator<<(std::ostream& o, const StringFormat& fmt)
{
o << fmt.toString();
return o;
}
} // namespace aria2

57
src/StringFormat.h Normal file
View File

@ -0,0 +1,57 @@
/* <!-- 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_STRING_FORMAT_H_
#define _D_STRING_FORMAT_H_
#include <string>
#include <iosfwd>
#include <cstdarg>
namespace aria2 {
class StringFormat {
private:
std::string _msg;
public:
StringFormat(const char* fmt, ...);
const std::string& toString() const;
};
std::ostream& operator<<(std::ostream& o, const StringFormat& fmt);
} // namespace aria2
#endif // _D_STRING_FORMAT_H_

View File

@ -42,6 +42,7 @@
#include "DefaultDiskWriter.h"
#include "FatalException.h"
#include "FileEntry.h"
#include "StringFormat.h"
#include <signal.h>
#include <cerrno>
#include <cassert>
@ -205,10 +206,7 @@ std::string Util::urlencode(const unsigned char* target, size_t len) {
std::string dest;
for(size_t i = 0; i < len; i++) {
if(shouldUrlencode(target[i])) {
char temp[4];
sprintf(temp, "%%%02x", target[i]);
temp[sizeof(temp)-1] = '\0';
dest.append(temp);
dest.append(StringFormat("%%%02x", target[i]).toString());
} else {
dest += target[i];
}
@ -224,10 +222,7 @@ std::string Util::torrentUrlencode(const unsigned char* target, size_t len) {
('a' <= target[i] && target[i] <= 'z')) {
dest += target[i];
} else {
char temp[4];
sprintf(temp, "%%%02x", target[i]);
temp[sizeof(temp)-1] = '\0';
dest.append(temp);
dest.append(StringFormat("%%%02x", target[i]).toString());
}
}
return dest;

View File

@ -44,6 +44,7 @@
#include "a2io.h"
#include "help_tags.h"
#include "File.h"
#include "StringFormat.h"
#include <cstdlib>
#include <fstream>
#include <sstream>
@ -523,8 +524,8 @@ Option* option_processing(int argc, char* const argv[])
exit(EXIT_FAILURE);
}
} else if(ucfname.size()) {
printf("Configuration file %s is not found.", cfname.c_str());
std::cout << "\n";
std::cout << StringFormat("Configuration file %s is not found.", cfname.c_str())
<< "\n";
}
}
try {

View File

@ -44,6 +44,7 @@
#include "HelpItemFactory.h"
#include "help_tags.h"
#include "prefs.h"
#include "StringFormat.h"
#include <iostream>
#include <iterator>
#include <algorithm>
@ -89,34 +90,34 @@ void showVersion() {
#ifdef ENABLE_MESSAGE_DIGEST
<< "message digest algorithms: " << MessageDigestContext::getSupportedAlgoString() << "\n"
#endif // ENABLE_MESSAGE_DIGEST
<< "\n";
printf(_("Report bugs to %s"), "<tujikawa at users dot sourceforge dot net>");
std::cout << std::endl;
<< "\n"
<< StringFormat(_("Report bugs to %s"), "<tujikawa at users dot sourceforge dot net>")
<< std::endl;
}
void showUsage(const std::string& category, const Option* option) {
printf(_("Usage: %s [options] URL ...\n"), PACKAGE_NAME);
std::cout << StringFormat(_("Usage: %s [options] URL ...\n"), PACKAGE_NAME)
#ifdef ENABLE_BITTORRENT
printf(_(" %s [options] -T TORRENT_FILE URL ...\n"), PACKAGE_NAME);
<< StringFormat(_(" %s [options] -T TORRENT_FILE URL ...\n"), PACKAGE_NAME)
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
printf(_(" %s [options] -M METALINK_FILE\n"), PACKAGE_NAME);
<< StringFormat(_(" %s [options] -M METALINK_FILE\n"), PACKAGE_NAME)
#endif // ENABLE_METALINK
std::cout << "\n";
<< "\n";
SharedHandle<TagContainer> tc = HelpItemFactory::createHelpItems(option);
std::deque<SharedHandle<TaggedItem> > items =
category == V_ALL ? tc->getAllItems() : tc->search(category);
if(items.size() > 0) {
if(category == V_ALL) {
printf(_("Printing all options."));
std::cout << _("Printing all options.");
} else {
printf(_("Printing options tagged with '%s'."), category.c_str());
std::cout << StringFormat(_("Printing options tagged with '%s'."), category.c_str());
std::cout << "\n";
SharedHandle<HelpItem> helpItem
(dynamic_pointer_cast<HelpItem>(tc->nameMatch("help")));
printf(_("See -h option to know other command-line options(%s)."),
helpItem->getAvailableValues().c_str());
std::cout << StringFormat(_("See -h option to know other command-line options(%s)."),
helpItem->getAvailableValues().c_str());
}
std::cout << "\n"
<< _("Options:") << "\n";
@ -126,13 +127,13 @@ void showUsage(const std::string& category, const Option* option) {
} else {
std::deque<SharedHandle<TaggedItem> > items = tc->nameMatchForward(category);
if(items.size() > 0) {
printf(_("Printing options whose name starts with '%s'."), category.c_str());
std::cout << "\n"
std::cout << StringFormat(_("Printing options whose name starts with '%s'."), category.c_str())
<< "\n"
<< _("Options:") << "\n";
std::copy(items.begin(), items.end(), std::ostream_iterator<SharedHandle<TaggedItem> >(std::cout, "\n"));
} else {
printf(_("No help category or option name matching with '%s'."), category.c_str());
std::cout << "\n" << tc->nameMatch("help") << "\n";
std::cout << StringFormat(_("No help category or option name matching with '%s'."), category.c_str())
<< "\n" << tc->nameMatch("help") << "\n";
}
}
if(category == TAG_BASIC) {

View File

@ -49,7 +49,8 @@ aria2c_SOURCES = AllTest.cc\
MultiDiskAdaptorTest.cc\
MultiFileAllocationIteratorTest.cc\
FixedNumberRandomizer.h\
ProtocolDetectorTest.cc
ProtocolDetectorTest.cc\
StringFormatTest.cc
if ENABLE_MESSAGE_DIGEST
aria2c_SOURCES += MessageDigestHelperTest.cc\

View File

@ -188,7 +188,8 @@ am__aria2c_SOURCES_DIST = AllTest.cc SocketCoreTest.cc \
FileTest.cc OptionTest.cc DefaultDiskWriterTest.cc \
FeatureConfigTest.cc SpeedCalcTest.cc MultiDiskAdaptorTest.cc \
MultiFileAllocationIteratorTest.cc FixedNumberRandomizer.h \
ProtocolDetectorTest.cc MessageDigestHelperTest.cc \
ProtocolDetectorTest.cc StringFormatTest.cc \
MessageDigestHelperTest.cc \
IteratableChunkChecksumValidatorTest.cc \
IteratableChecksumValidatorTest.cc BtAllowedFastMessageTest.cc \
BtBitfieldMessageTest.cc BtCancelMessageTest.cc \
@ -350,8 +351,8 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) SocketCoreTest.$(OBJEXT) \
DefaultDiskWriterTest.$(OBJEXT) FeatureConfigTest.$(OBJEXT) \
SpeedCalcTest.$(OBJEXT) MultiDiskAdaptorTest.$(OBJEXT) \
MultiFileAllocationIteratorTest.$(OBJEXT) \
ProtocolDetectorTest.$(OBJEXT) $(am__objects_1) \
$(am__objects_2) $(am__objects_3)
ProtocolDetectorTest.$(OBJEXT) StringFormatTest.$(OBJEXT) \
$(am__objects_1) $(am__objects_2) $(am__objects_3)
aria2c_OBJECTS = $(am_aria2c_OBJECTS)
am__DEPENDENCIES_1 =
aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@ -587,8 +588,8 @@ aria2c_SOURCES = AllTest.cc SocketCoreTest.cc array_funTest.cc \
FileTest.cc OptionTest.cc DefaultDiskWriterTest.cc \
FeatureConfigTest.cc SpeedCalcTest.cc MultiDiskAdaptorTest.cc \
MultiFileAllocationIteratorTest.cc FixedNumberRandomizer.h \
ProtocolDetectorTest.cc $(am__append_1) $(am__append_2) \
$(am__append_3)
ProtocolDetectorTest.cc StringFormatTest.cc $(am__append_1) \
$(am__append_2) $(am__append_3)
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
#aria2c_LDFLAGS = ${CPPUNIT_LIBS}
@ -794,6 +795,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SingletonHolderTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SocketCoreTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpeedCalcTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringFormatTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TagContainerTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TaggedItemTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@

35
test/StringFormatTest.cc Normal file
View File

@ -0,0 +1,35 @@
#include "StringFormat.h"
#include "Exception.h"
#include "Util.h"
#include <iostream>
#include <cppunit/extensions/HelperMacros.h>
namespace aria2 {
class StringFormatTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(StringFormatTest);
CPPUNIT_TEST(testGetString);
CPPUNIT_TEST_SUITE_END();
public:
void setUp() {}
void tearDown() {}
void testGetString();
};
CPPUNIT_TEST_SUITE_REGISTRATION(StringFormatTest);
void StringFormatTest::testGetString()
{
int major = 1;
int minor = 0;
int release = 7;
StringFormat fmt("aria2-%d.%d.%d-%s", major, minor, release, "beta");
CPPUNIT_ASSERT_EQUAL(std::string("aria2-1.0.7-beta"), fmt.toString());
}
} // namespace aria2