diff options
author | randomdan <randomdan@localhost> | 2013-08-19 00:12:10 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2013-08-19 00:12:10 +0000 |
commit | fcb01c9a58c4406de58d87027d5f539b8932912a (patch) | |
tree | 8edea8092020fe815c7bdb83c2f1c79435cd25fc | |
parent | Take local copies of settings, config reload can screw them over (diff) | |
download | project2-fcb01c9a58c4406de58d87027d5f539b8932912a.tar.bz2 project2-fcb01c9a58c4406de58d87027d5f539b8932912a.tar.xz project2-fcb01c9a58c4406de58d87027d5f539b8932912a.zip |
Fix the schoolboy error with buffer allocation in base exception classes
-rw-r--r-- | project2/common/exceptions.cpp | 78 | ||||
-rw-r--r-- | project2/common/exceptions.h | 35 |
2 files changed, 60 insertions, 53 deletions
diff --git a/project2/common/exceptions.cpp b/project2/common/exceptions.cpp index 9be2710..29b4fa0 100644 --- a/project2/common/exceptions.cpp +++ b/project2/common/exceptions.cpp @@ -1,75 +1,71 @@ #include <pch.hpp> #include "exceptions.h" -#include "logger.h" -#include <stdlib.h> -#include <stdio.h> #include <error.h> +#include <boost/format.hpp> -numeric_error::numeric_error(int e) : - err(e), - buf(NULL) +std::string +sprintbf(boost::format & fmt) { + return fmt.str(); } -numeric_error::~numeric_error() throw() +template <typename Arg, typename... Args> +std::string +sprintbf(boost::format & fmt, const Arg & arg, const Args & ... args) { - free(buf); + fmt % arg; + return sprintbf(fmt, args...); +} + +template <typename... Args> +std::string +sprintbf(const std::string & fmt, const Args & ... args) +{ + boost::format f(fmt); + return sprintbf(f, args...); } const char * -numeric_error::what() const throw() +MsgBufferedException::what() const throw() { if (!buf) { - if (asprintf(&buf, "%d", err) < 1) { - throw std::bad_alloc(); - } + buf = msg(); } - return buf; + return buf->c_str(); } -two_part_error::two_part_error(const std::string & w1, const std::string & w2) : - what1(w1), - what2(w2), - buf(NULL) +numeric_error::numeric_error(int e) : + err(e) { } -two_part_error::~two_part_error() throw() +std::string +numeric_error::msg() const throw() { - free(buf); + return sprintbf("%d", err); } -const char * -two_part_error::what() const throw() +two_part_error::two_part_error(const std::string & w1, const std::string & w2) : + what1(w1), + what2(w2) { - if (!buf) { - if (asprintf(&buf, "%s, %s", what1.c_str(), what2.c_str()) < 1) { - throw std::bad_alloc(); - } - } - return buf; } - -syscall_error::syscall_error(int e) : - err(e), - buf(NULL) +std::string +two_part_error::msg() const throw() { + return sprintbf("%s, %s", what1, what2); } -syscall_error::~syscall_error() throw() + +syscall_error::syscall_error(int e) : + err(e) { - free(buf); } -const char * -syscall_error::what() const throw() +std::string +syscall_error::msg() const throw() { - if (!buf) { - if (asprintf(&buf, "%s (%d)", strerror(err), err) < 1) { - throw std::bad_alloc(); - } - } - return buf; + return sprintbf("%s (%d)", strerror(err), err); } diff --git a/project2/common/exceptions.h b/project2/common/exceptions.h index 9cdf6f0..123afc9 100644 --- a/project2/common/exceptions.h +++ b/project2/common/exceptions.h @@ -2,35 +2,46 @@ #define EXCEPTION_H #include <stdexcept> +#include <boost/optional.hpp> -class numeric_error : public std::exception { +class MsgBufferedException : public std::exception { public: - numeric_error(int); - ~numeric_error() throw(); + inline ~MsgBufferedException() throw() { } const char * what() const throw(); + protected: + virtual std::string msg() const throw() = 0; + private: + mutable boost::optional<std::string> buf; +}; + +class numeric_error : public MsgBufferedException { + public: + numeric_error(int); + protected: + std::string msg() const throw(); private: int err; - mutable char * buf; }; -class syscall_error : public std::exception { + +class syscall_error : public MsgBufferedException { public: syscall_error(int); - ~syscall_error() throw(); - const char * what() const throw(); + protected: + std::string msg() const throw(); private: int err; - mutable char * buf; }; -class two_part_error : public std::exception { + +class two_part_error : public MsgBufferedException { public: two_part_error(const std::string & what1, const std::string & what2); - ~two_part_error() throw(); - const char * what() const throw(); + protected: + std::string msg() const throw(); private: const std::string what1; const std::string what2; - mutable char * buf; }; + #define StaticMessageException(Name, Text) \ class Name : public std::runtime_error { \ public: \ |