Author: kpvdr
Date: 2007-11-16 15:07:46 -0500 (Fri, 16 Nov 2007)
New Revision: 1328
Modified:
store/trunk/cpp/lib/jrnl/jexception.cpp
store/trunk/cpp/lib/jrnl/jexception.hpp
store/trunk/cpp/tests/jrnl/unit_test_jexception.cpp
Log:
Another fix to jexception and its unit test class. It now handles null strings and strings
that exceed its internal buffer space.
Modified: store/trunk/cpp/lib/jrnl/jexception.cpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jexception.cpp 2007-11-16 19:55:33 UTC (rev 1327)
+++ store/trunk/cpp/lib/jrnl/jexception.cpp 2007-11-16 20:07:46 UTC (rev 1328)
@@ -33,9 +33,11 @@
#include <jrnl/jexception.hpp>
#include <iomanip>
+#include <iostream> // debug only
#include <sstream>
#include <jrnl/jerrno.hpp>
+#define CATLEN(p) MAX_MSG_SIZE - ::strlen(p) - 1
namespace rhm
{
@@ -46,6 +48,7 @@
std::exception(),
_err_code(0)
{
+ ::sprintf(_what_msg, "jexception 0x0000");
*_additional_info = '\0';
*_throwing_class = '\0';
*_throwing_fn = '\0';
@@ -55,6 +58,7 @@
std::exception(),
_err_code(err_code)
{
+ ::sprintf(_what_msg, "jexception 0x%04X", err_code);
*_additional_info = '\0';
*_throwing_class = '\0';
*_throwing_fn = '\0';
@@ -64,7 +68,15 @@
std::exception(),
_err_code(0)
{
- if (additional_info) ::strncpy(_additional_info, additional_info, MAX_MSG_SIZE);
+ ::sprintf(_what_msg, "jexception ");
+ if (additional_info)
+ {
+ ::strncpy(_additional_info, additional_info, MAX_MSG_SIZE - 1);
+ _additional_info[MAX_MSG_SIZE - 1] = '\0';
+ ::strncat(_what_msg, _additional_info, CATLEN(_what_msg));
+ }
+ else
+ *_additional_info = '\0';
*_throwing_class = '\0';
*_throwing_fn = '\0';
}
@@ -73,7 +85,15 @@
std::exception(),
_err_code(err_code)
{
- if (additional_info) ::strncpy(_additional_info, additional_info, MAX_MSG_SIZE);
+ ::sprintf(_what_msg, "jexception 0x%04X ", err_code);
+ if (additional_info)
+ {
+ ::strncpy(_additional_info, additional_info, MAX_MSG_SIZE - 1);
+ _additional_info[MAX_MSG_SIZE - 1] = '\0';
+ ::strncat(_what_msg, _additional_info, CATLEN(_what_msg));
+ }
+ else
+ *_additional_info = '\0';
*_throwing_class = '\0';
*_throwing_fn = '\0';
}
@@ -83,9 +103,26 @@
std::exception(),
_err_code(err_code)
{
+ ::sprintf(_what_msg, "jexception 0x%04X ", err_code);
*_additional_info = '\0';
- if (throwing_class) ::strncpy(_throwing_class, throwing_class, MAX_THROWING_SIZE);
- if (throwing_fn) ::strncpy(_throwing_fn, throwing_fn, MAX_THROWING_SIZE);
+ if (throwing_class)
+ {
+ ::strncpy(_throwing_class, throwing_class, MAX_THROWING_SIZE - 1);
+ _throwing_class[MAX_THROWING_SIZE - 1] = '\0';
+ ::strncat(_what_msg, _throwing_class, CATLEN(_what_msg));
+ if (throwing_fn)
+ ::strncat(_what_msg, "::", CATLEN(_what_msg));
+ }
+ else
+ *_throwing_class = '\0';
+ if (throwing_fn)
+ {
+ ::strncpy(_throwing_fn, throwing_fn, MAX_THROWING_SIZE - 1);
+ _throwing_fn[MAX_THROWING_SIZE - 1] = '\0';
+ ::strncat(_what_msg, _throwing_fn, CATLEN(_what_msg));
+ }
+ else
+ *_throwing_fn = '\0';
}
jexception::jexception(const u_int32_t err_code, const char* additional_info,
@@ -93,9 +130,37 @@
std::exception(),
_err_code(err_code)
{
- if (additional_info) ::strncpy(_additional_info, additional_info, MAX_MSG_SIZE);
- if (throwing_class) ::strncpy(_throwing_class, throwing_class, MAX_THROWING_SIZE);
- if (throwing_fn) ::strncpy(_throwing_fn, throwing_fn, MAX_THROWING_SIZE);
+ ::sprintf(_what_msg, "jexception 0x%04X ", err_code);
+ if (throwing_class)
+ {
+ ::strncpy(_throwing_class, throwing_class, MAX_THROWING_SIZE - 1);
+ _throwing_class[MAX_THROWING_SIZE - 1] = '\0';
+ ::strncat(_what_msg, _throwing_class, CATLEN(_what_msg));
+ if (throwing_fn)
+ ::strncat(_what_msg, "::", CATLEN(_what_msg));
+ else if (additional_info)
+ ::strncat(_what_msg, " ", CATLEN(_what_msg));
+ }
+ else
+ *_throwing_class = '\0';
+ if (throwing_fn)
+ {
+ ::strncpy(_throwing_fn, throwing_fn, MAX_THROWING_SIZE - 1);
+ _throwing_fn[MAX_THROWING_SIZE - 1] = '\0';
+ ::strncat(_what_msg, _throwing_fn, CATLEN(_what_msg));
+ if (additional_info)
+ ::strncat(_what_msg, " ", CATLEN(_what_msg));
+ }
+ else
+ *_throwing_fn = '\0';
+ if (additional_info)
+ {
+ ::strncpy(_additional_info, additional_info, MAX_MSG_SIZE - 1);
+ _additional_info[MAX_MSG_SIZE - 1] = '\0';
+ ::strncat(_what_msg, _additional_info, CATLEN(_what_msg));
+ }
+ else
+ *_additional_info = '\0';
}
jexception::~jexception() throw ()
@@ -104,14 +169,7 @@
const char*
jexception::what() const throw ()
{
- std::stringstream ss;
- if (::strlen(_throwing_class) &&::strlen( _throwing_fn))
- ss << _throwing_class << "::" << _throwing_fn
<< "() threw ";
- ss << "jexception: 0x" << std::hex << std::setw(4)
<< std::setfill('0') << _err_code;
- ss << " " << jerrno::err_msg(_err_code);
- if (::strlen(_additional_info))
- ss << " (" << _additional_info << ")";
- return ss.str().c_str();
+ return _what_msg;
}
std::ostream&
Modified: store/trunk/cpp/lib/jrnl/jexception.hpp
===================================================================
--- store/trunk/cpp/lib/jrnl/jexception.hpp 2007-11-16 19:55:33 UTC (rev 1327)
+++ store/trunk/cpp/lib/jrnl/jexception.hpp 2007-11-16 20:07:46 UTC (rev 1328)
@@ -62,6 +62,7 @@
{
private:
u_int32_t _err_code;
+ char _what_msg[MAX_MSG_SIZE];
char _additional_info[MAX_MSG_SIZE];
char _throwing_class[MAX_THROWING_SIZE];
char _throwing_fn[MAX_THROWING_SIZE];
Modified: store/trunk/cpp/tests/jrnl/unit_test_jexception.cpp
===================================================================
--- store/trunk/cpp/tests/jrnl/unit_test_jexception.cpp 2007-11-16 19:55:33 UTC (rev
1327)
+++ store/trunk/cpp/tests/jrnl/unit_test_jexception.cpp 2007-11-16 20:07:46 UTC (rev
1328)
@@ -38,6 +38,12 @@
using namespace boost::unit_test;
using namespace rhm::journal;
+// Helper function declarations
+void throw_exception(const jexception& e, size_t what_len, size_t ai_len);
+void throw_exception(const jexception& e, size_t what_len, size_t tc_len, size_t
tf_len);
+void throw_exception(const jexception& e, size_t what_len, size_t ai_len, size_t
tc_len,
+ size_t tf_len);
+
// Test functions of the form
// void fn() {...}
@@ -201,6 +207,111 @@
BOOST_CHECK(ss.str().size() > 0);
}
}
+
+void test_long_null_strings()
+{
+ // msg 1500 chars long; every 50th char is a '*'
+ const char* long_msg =
+ "Long_message_456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*";
+ // throwing class and function 250 chars long
+ const char* long_throwing_class =
+ "Long_throwing_class_12345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*";
+ const char* long_throwing_fn =
+ "Long_throwing_function_45678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*"
+ "1234567890123456789012345678901234567890123456789*";
+
+
+ throw_exception(jexception(long_msg), MAX_MSG_SIZE - 1, MAX_MSG_SIZE - 1);
+ throw_exception(jexception((const char*)NULL), 11, 0);
+
+ throw_exception(jexception(0x1234, long_msg), MAX_MSG_SIZE - 1, MAX_MSG_SIZE - 1);
+ throw_exception(jexception(0x1234, NULL), 18, 0);
+
+ throw_exception(jexception(0x1234, long_throwing_class, long_throwing_fn),
+ (2 * (MAX_THROWING_SIZE - 1)) + 20, MAX_THROWING_SIZE - 1, MAX_THROWING_SIZE
- 1);
+ throw_exception(jexception(0x1234, long_throwing_class, NULL), MAX_THROWING_SIZE - 1
+ 18,
+ MAX_THROWING_SIZE - 1, 0);
+ throw_exception(jexception(0x1234, NULL, long_throwing_fn), MAX_THROWING_SIZE - 1 +
18, 0,
+ MAX_THROWING_SIZE - 1);
+ throw_exception(jexception(0x1234, NULL, NULL), 18, 0, 0);
+
+ throw_exception(jexception(0x1234, long_msg, long_throwing_class, long_throwing_fn),
+ MAX_MSG_SIZE - 1, MAX_MSG_SIZE - 1, MAX_THROWING_SIZE - 1, MAX_THROWING_SIZE
- 1);
+ throw_exception(jexception(0x1234, long_msg, long_throwing_class, NULL), MAX_MSG_SIZE
- 1,
+ MAX_MSG_SIZE - 1, MAX_THROWING_SIZE - 1, 0);
+ throw_exception(jexception(0x1234, long_msg, NULL, long_throwing_fn), MAX_MSG_SIZE -
1,
+ MAX_MSG_SIZE - 1, 0, MAX_THROWING_SIZE - 1);
+ throw_exception(jexception(0x1234, long_msg, NULL, NULL), MAX_MSG_SIZE - 1,
MAX_MSG_SIZE - 1, 0,
+ 0);
+ throw_exception(jexception(0x1234, NULL, long_throwing_class, long_throwing_fn),
+ (2 * (MAX_THROWING_SIZE - 1)) + 20, 0, MAX_THROWING_SIZE - 1,
MAX_THROWING_SIZE - 1);
+ throw_exception(jexception(0x1234, NULL, long_throwing_class, NULL),
MAX_THROWING_SIZE - 1 + 18,
+ 0, MAX_THROWING_SIZE - 1, 0);
+ throw_exception(jexception(0x1234, NULL, NULL, long_throwing_fn), MAX_THROWING_SIZE -
1 + 18, 0,
+ 0, MAX_THROWING_SIZE - 1);
+ throw_exception(jexception(0x1234, NULL, NULL, NULL), 18, 0, 0, 0);
+}
+
+// Helper functions
+
+void throw_exception(const jexception& e, size_t what_len, size_t ai_len)
+{
+ throw_exception(e, what_len, ai_len, 0, 0);
+}
+
+void throw_exception(const jexception& e, size_t what_len, size_t tc_len, size_t
tf_len)
+{
+ throw_exception(e, what_len, 0, tc_len, tf_len);
+}
+
+void throw_exception(const jexception& e, size_t what_len, size_t ai_len, size_t
tc_len,
+ size_t tf_len)
+{
+ try { throw e; }
+ catch (const jexception& e)
+ {
+ BOOST_CHECK_EQUAL(::strlen(e.what()), what_len);
+ BOOST_CHECK_EQUAL(::strlen(e.additional_info()), ai_len);
+ BOOST_CHECK_EQUAL(::strlen(e.throwing_class()), tc_len);
+ BOOST_CHECK_EQUAL(::strlen(e.throwing_fn()), tf_len);
+ }
+}
// Initialize test suite and include test functions
@@ -219,6 +330,7 @@
ts->add(BOOST_TEST_CASE(&test_constructor_5));
ts->add(BOOST_TEST_CASE(&test_constructor_6));
ts->add(BOOST_TEST_CASE(&test_msg_scope));
+ ts->add(BOOST_TEST_CASE(&test_long_null_strings));
return ts;
}