diff --git a/src/BufferedFile.cc b/src/BufferedFile.cc index f0096326..d1af1c09 100644 --- a/src/BufferedFile.cc +++ b/src/BufferedFile.cc @@ -156,13 +156,9 @@ size_t BufferedFile::transfer(std::ostream& out) return count; } -int BufferedFile::printf(const char* format, ...) +int BufferedFile::vprintf(const char* format, va_list va) { - va_list ap; - va_start(ap, format); - int r = vfprintf(fp_, format, ap); - va_end(ap); - return r; + return vfprintf(fp_, format, va); } int BufferedFile::flush() diff --git a/src/BufferedFile.h b/src/BufferedFile.h index 0e267f0a..f0d78e07 100644 --- a/src/BufferedFile.h +++ b/src/BufferedFile.h @@ -73,8 +73,7 @@ public: // Convenient method. Read data to end of file and write them into // given stream. Returns written size. size_t transfer(std::ostream& out); - // wrapper for fprintf - virtual int printf(const char* format, ...); + virtual int vprintf(const char* format, va_list va); // wrapper for fflush virtual int flush(); virtual bool supportsColor(); diff --git a/src/NullOutputFile.h b/src/NullOutputFile.h index c152f108..ff14ef1b 100644 --- a/src/NullOutputFile.h +++ b/src/NullOutputFile.h @@ -43,7 +43,7 @@ class NullOutputFile:public OutputFile { public: virtual ~NullOutputFile() {} virtual size_t write(const char* str) { return 0; } - virtual int printf(const char* format, ...) { return 0; } + virtual int vprintf(const char* format, va_list va) { return 0; } virtual int flush() { return 0; } virtual bool supportsColor() { return false; } }; diff --git a/src/OutputFile.h b/src/OutputFile.h index ba0ccb3f..77e88991 100644 --- a/src/OutputFile.h +++ b/src/OutputFile.h @@ -38,6 +38,7 @@ #include "common.h" #include +#include namespace aria2 { @@ -45,8 +46,15 @@ class OutputFile { public: virtual ~OutputFile() {} virtual size_t write(const char* str) = 0; - virtual int printf(const char* format, ...) = 0; virtual int flush() = 0; + virtual int vprintf(const char* format, va_list va) = 0; + inline int printf(const char *format, ...) { + va_list va; + va_start(va, format); + int rv = vprintf(format, va); + va_end(va); + return rv; + } // Returns true if the output medium supports ANSI color codes. virtual bool supportsColor() = 0; }; diff --git a/src/WinConsoleFile.cc b/src/WinConsoleFile.cc index 0938d89d..157a2e36 100644 --- a/src/WinConsoleFile.cc +++ b/src/WinConsoleFile.cc @@ -72,18 +72,16 @@ size_t WinConsoleFile::write(const char* str) return written; } -int WinConsoleFile::printf(const char* format, ...) +int WinConsoleFile::vprintf(const char* format, va_list va) { - char buf[2048]; - va_list ap; - va_start(ap, format); - int r = vsnprintf(buf, sizeof(buf), format, ap); - va_end(ap); - if(r == -1) { - // MINGW32 vsnprintf returns -1 if output is truncated. - r = strlen(buf); - } else if(r < 0) { - // Reachable? + ssize_t r = _vscprintf(format, va); + if (r <= 0) { + return 0; + } + char *buf = new char[++r]; + r = vsnprintf(buf, r, format, va); + if (r < 0) { + delete [] buf; return 0; } DWORD written; @@ -95,6 +93,7 @@ int WinConsoleFile::printf(const char* format, ...) WriteFile(GetStdHandle(stdHandle_), buf, r, &written, 0); } + delete [] buf; return written; } diff --git a/src/WinConsoleFile.h b/src/WinConsoleFile.h index ccd2388f..b39d292e 100644 --- a/src/WinConsoleFile.h +++ b/src/WinConsoleFile.h @@ -45,7 +45,7 @@ public: WinConsoleFile(DWORD stdHandle); virtual ~WinConsoleFile(); virtual size_t write(const char* str); - virtual int printf(const char* format, ...); + virtual int vprintf(const char* format, va_list va); virtual int flush(); virtual bool supportsColor(); private: