From 698f4911ba49deef19aa1bbc2c5a64aab120b568 Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Fri, 28 Jan 2011 19:50:05 +0100 Subject: [PATCH] BaseException fix and cleanup. --- pvDataApp/misc/StatusCreateFactory.cpp | 4 +- pvDataApp/misc/byteBuffer.cpp | 55 +++++++++++----------- pvDataApp/misc/byteBuffer.h | 4 +- pvDataApp/misc/epicsException.h | 64 ++++++++------------------ pvDataApp/misc/serializeHelper.cpp | 2 +- testApp/misc/testBaseException.cpp | 17 +++---- 6 files changed, 57 insertions(+), 89 deletions(-) diff --git a/pvDataApp/misc/StatusCreateFactory.cpp b/pvDataApp/misc/StatusCreateFactory.cpp index 86e9f4c..a6f4965 100644 --- a/pvDataApp/misc/StatusCreateFactory.cpp +++ b/pvDataApp/misc/StatusCreateFactory.cpp @@ -176,9 +176,7 @@ class StatusCreateImpl : public StatusCreate { return new StatusImpl(type, message); else { - std::string stackDump; - cause->toString(stackDump); - return new StatusImpl(type, message, stackDump); + return new StatusImpl(type, message, cause->what()); } } diff --git a/pvDataApp/misc/byteBuffer.cpp b/pvDataApp/misc/byteBuffer.cpp index d04e68b..c39317c 100644 --- a/pvDataApp/misc/byteBuffer.cpp +++ b/pvDataApp/misc/byteBuffer.cpp @@ -13,6 +13,7 @@ #include "byteBuffer.h" #include "epicsException.h" +// TODO optimize, avoid so many checks (endianness, positions), allow wrapping of external buffer, chance of endianess namespace epics { namespace pvData { @@ -22,10 +23,10 @@ namespace epics { _bufferByteOrder(byteOrder), _size(size), _position(0), _limit(size), _buffer(0) { - if(size<0) throw EpicsException("negative size"); + if(size<0) THROW_BASE_EXCEPTION("negative size"); if (byteOrder!=EPICS_ENDIAN_BIG && byteOrder!=EPICS_ENDIAN_LITTLE) - throw EpicsException("invalid endianness"); + THROW_BASE_EXCEPTION("invalid endianness"); _buffer = new char[_size]; } @@ -59,7 +60,7 @@ namespace epics { if(index>=0&&index<_limit) return _buffer[index]==0 ? false : true; else - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); } int8 ByteBuffer::getByte() { @@ -70,12 +71,12 @@ namespace epics { if(index>=0&&index<_limit) return (int8)_buffer[index]; else - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); } int16 ByteBuffer::getShort() { if(_limit-_position<(int)sizeof(int16)) - throw EpicsException("buffer underflow"); + THROW_BASE_EXCEPTION("buffer underflow"); int16 val; getWithEndianness((char*)&val, sizeof(int16)); // store short into val return val; @@ -83,7 +84,7 @@ namespace epics { int16 ByteBuffer::getShort(int index) { if(index<0||_limit-index<(int)sizeof(int16)) - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); int16 val; getWithEndianness(index, (char*)&val, sizeof(int16)); // store short into val return val; @@ -92,7 +93,7 @@ namespace epics { int32 ByteBuffer::getInt() { if(_limit-_position<(int)sizeof(int32)) - throw EpicsException("buffer underflow"); + THROW_BASE_EXCEPTION("buffer underflow"); int32 val; getWithEndianness((char*)&val, sizeof(int32)); // store int into val return val; @@ -100,7 +101,7 @@ namespace epics { int32 ByteBuffer::getInt(int index) { if(index<0||_limit-index<(int)sizeof(int32)) - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); int32 val; getWithEndianness(index, (char*)&val, sizeof(int32)); // store int into val return val; @@ -108,7 +109,7 @@ namespace epics { int64 ByteBuffer::getLong() { if(_limit-_position<(int)sizeof(int64)) - throw EpicsException("buffer underflow"); + THROW_BASE_EXCEPTION("buffer underflow"); int64 val; getWithEndianness((char*)&val, sizeof(int64)); // store long into val return val; @@ -116,7 +117,7 @@ namespace epics { int64 ByteBuffer::getLong(int index) { if(index<0||_limit-index<(int)sizeof(int64)) - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); int64 val; getWithEndianness(index, (char*)&val, sizeof(int64)); // store long into val return val; @@ -124,7 +125,7 @@ namespace epics { float ByteBuffer::getFloat() { if(_limit-_position<(int)sizeof(float)) - throw EpicsException("buffer underflow"); + THROW_BASE_EXCEPTION("buffer underflow"); float val; getWithEndianness((char*)&val, sizeof(float)); // store float into val return val; @@ -132,7 +133,7 @@ namespace epics { float ByteBuffer::getFloat(int index) { if(index<0||_limit-index<(int)sizeof(float)) - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); float val; getWithEndianness(index, (char*)&val, sizeof(float)); // store float into val return val; @@ -140,14 +141,14 @@ namespace epics { double ByteBuffer::getDouble() { if(_limit-_position<(int)sizeof(double)) - throw EpicsException("buffer underflow"); + THROW_BASE_EXCEPTION("buffer underflow"); double val; getWithEndianness((char*)&val, sizeof(double)); // store double into val return val; } double ByteBuffer::getDouble(int index) { - if(index>=0&&_limit-index<(int)sizeof(double)) throw EpicsException( + if(index>=0&&_limit-index<(int)sizeof(double)) THROW_BASE_EXCEPTION( "index out of bounds"); double val; getWithEndianness(index, (char*)&val, sizeof(double)); // store double into val @@ -155,13 +156,13 @@ namespace epics { } void ByteBuffer::get(char* dst, int offset, int count) { - if(count>getRemaining()) throw EpicsException("buffer underflow"); + if(count>getRemaining()) THROW_BASE_EXCEPTION("buffer underflow"); for(int i = 0; igetRemaining()) throw EpicsException("buffer overflow"); + if(count>getRemaining()) THROW_BASE_EXCEPTION("buffer overflow"); for(int i = 0; i=0&&index<_limit) _buffer[index] = (char)value; else - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); return this; } ByteBuffer* ByteBuffer::putShort(int16 value) { if(_limit-_position<(int)sizeof(int16)) - throw EpicsException("buffer overflow"); + THROW_BASE_EXCEPTION("buffer overflow"); putWithEndianness((char*)&value, sizeof(int16)); // store short into buffer return this; } ByteBuffer* ByteBuffer::putShort(int index, int16 value) { if(index<0||_limit-index<(int)sizeof(int16)) - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); putWithEndianness(index, (char*)&value, sizeof(int16)); // store short into buffer return this; } ByteBuffer* ByteBuffer::putInt(int32 value) { if(_limit-_position<(int)sizeof(int32)) - throw EpicsException("buffer overflow"); + THROW_BASE_EXCEPTION("buffer overflow"); putWithEndianness((char*)&value, sizeof(int32)); // store int into buffer return this; } ByteBuffer* ByteBuffer::putInt(int index, int32 value) { if(index<0||_limit-index<(int)sizeof(int32)) - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); putWithEndianness(index, (char*)&value, sizeof(int32)); // store int into buffer return this; } ByteBuffer* ByteBuffer::putLong(int64 value) { if(_limit-_position<(int)sizeof(int64)) - throw EpicsException("buffer overflow"); + THROW_BASE_EXCEPTION("buffer overflow"); putWithEndianness((char*)&value, sizeof(int64)); // store long into buffer return this; } ByteBuffer* ByteBuffer::putLong(int index, int64 value) { if(index<0||_limit-index<(int)sizeof(int64)) - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); putWithEndianness(index, (char*)&value, sizeof(int64)); // store long into buffer return this; } ByteBuffer* ByteBuffer::putFloat(float value) { if(_limit-_position<(int)sizeof(float)) - throw EpicsException("buffer overflow"); + THROW_BASE_EXCEPTION("buffer overflow"); putWithEndianness((char*)&value, sizeof(float)); // store float into buffer return this; } ByteBuffer* ByteBuffer::putFloat(int index, float value) { if(index<0||_limit-index<(int)sizeof(float)) - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); putWithEndianness(index, (char*)&value, sizeof(float)); // store float into buffer return this; } ByteBuffer* ByteBuffer::putDouble(double value) { if(_limit-_position<(int)sizeof(double)) - throw EpicsException("buffer overflow"); + THROW_BASE_EXCEPTION("buffer overflow"); putWithEndianness((char*)&value, sizeof(double)); // store double into buffer return this; } ByteBuffer* ByteBuffer::putDouble(int index, double value) { if(index<0||_limit-index<(int)sizeof(double)) - throw EpicsException("index out of bounds"); + THROW_BASE_EXCEPTION("index out of bounds"); putWithEndianness(index, (char*)&value, sizeof(double)); // store double into buffer return this; } diff --git a/pvDataApp/misc/byteBuffer.h b/pvDataApp/misc/byteBuffer.h index 75ea78f..0723fb4 100644 --- a/pvDataApp/misc/byteBuffer.h +++ b/pvDataApp/misc/byteBuffer.h @@ -455,13 +455,13 @@ namespace epics { * {@code newPosition} do not hold */ inline void setPosition(int newPosition) { - if(newPosition<0||newPosition>_limit) throw EpicsException( + if(newPosition<0||newPosition>_limit) THROW_BASE_EXCEPTION( "invalid limit"); _position = newPosition; } inline void setLimit(int newLimit) { - if(newLimit<0||_position>newLimit) throw EpicsException( + if(newLimit<0||_position>newLimit) THROW_BASE_EXCEPTION( "invalid limit"); _limit = newLimit; } diff --git a/pvDataApp/misc/epicsException.h b/pvDataApp/misc/epicsException.h index 8c6755d..a69d0d2 100644 --- a/pvDataApp/misc/epicsException.h +++ b/pvDataApp/misc/epicsException.h @@ -14,8 +14,6 @@ #ifndef EPICSEXCEPTION_H_ #define EPICSEXCEPTION_H_ -// TODO to be redefined!!!!!! - #include #include @@ -30,42 +28,35 @@ namespace epics { namespace pvData { class BaseException : public std::exception { public: - BaseException(const char* message, const char* file, int line, std::exception* cause = 0) - : m_msg(message), m_file(file), m_line(line), m_cause(cause) + BaseException(const char* message, const char* file, int line) { - getStackTrace(&m_stackTrace); + toString(m_what, message, file, line, 0); + } + + BaseException(const char* message, const char* file, int line, std::exception& cause) + { + toString(m_what, message, file, line, cause.what()); } virtual ~BaseException() throw() { - if (m_cause) delete m_cause; } - virtual const char* what() const throw() { return m_msg.c_str(); } + virtual const char* what() const throw() { return m_what.c_str(); } - const char* getFile() const { return m_file.c_str(); } - int getLine() const { return m_line; } - - void toString(std::string& str, unsigned int depth = 0) { - str.append("BaseException: "); - str.append(m_msg); +private: + static inline void toString(std::string& str, const char* message, const char* file, int line, const char * cause) { + str.append(message); str.append("\n\tat "); - str.append(m_file); + str.append(file); str.append(":"); char sline[10]; - snprintf(sline, 10, "%d", m_line); + snprintf(sline, 10, "%d", line); str.append(sline); str.append("\n"); - str.append(m_stackTrace); - if (m_cause) - { - str.append("caused by: "); - BaseException *be = dynamic_cast(m_cause); - if (be) - be->toString(str, depth+1); - else - str.append(m_cause->what()); - } + getStackTrace(&str); + if (cause) + str.append(cause); } /** Get stack trace, i.e. demangled backtrace of the caller. */ @@ -200,30 +191,13 @@ public: } private: - std::string m_msg; - std::string m_file; - int m_line; - std::exception* m_cause; - std::string m_stackTrace; + std::string m_what; }; -#define THROW_BASE_EXCEPTION(msg) throw new BaseException(msg, __FILE__, __LINE__) -#define THROW_BASE_EXCEPTION_CAUSE(msg, cause) throw new BaseException(msg, __FILE__, __LINE__, cause) +#define THROW_BASE_EXCEPTION(msg) throw ::epics::pvData::BaseException(msg, __FILE__, __LINE__) +#define THROW_BASE_EXCEPTION_CAUSE(msg, cause) throw ::epics::pvData::BaseException(msg, __FILE__, __LINE__, cause) -/* - /// Construct with file, line info and printf-type arguments. - GenericException(const char *sourcefile, size_t line, const char *format, ...) - __attribute__ ((format (printf, 4, 5))); -*/ - - /** Base Epics Exception */ - class EpicsException : public std::logic_error { - public: - explicit EpicsException(const std::string& arg) : - std::logic_error(arg) { - } - }; } } diff --git a/pvDataApp/misc/serializeHelper.cpp b/pvDataApp/misc/serializeHelper.cpp index 566620a..88057cd 100644 --- a/pvDataApp/misc/serializeHelper.cpp +++ b/pvDataApp/misc/serializeHelper.cpp @@ -47,7 +47,7 @@ namespace epics { else if(b==-2) { control->ensureData(sizeof(int32)); int32 s = buffer->getInt(); - if(s<0) throw EpicsException("negative array size"); + if(s<0) THROW_BASE_EXCEPTION("negative array size"); return s; } else diff --git a/testApp/misc/testBaseException.cpp b/testApp/misc/testBaseException.cpp index c2cefed..0c6f1b9 100644 --- a/testApp/misc/testBaseException.cpp +++ b/testApp/misc/testBaseException.cpp @@ -36,7 +36,7 @@ void internalTestBaseException(int unused = 0) try { // NOTE: 5, 4, 3, 2, 1 calls will be optimized and not shown Unroller().unroll<5>(42.0); - } catch (BaseException *be3) { + } catch (BaseException& be3) { THROW_BASE_EXCEPTION_CAUSE("exception 1", be3); } } @@ -46,23 +46,18 @@ void testBaseException() { try { THROW_BASE_EXCEPTION("all is OK"); - } catch (BaseException *be) { - std::string str; - be->toString(str); - printf("\n\n%s\n\n", str.c_str()); + } catch (BaseException& be) { + printf("\n\n%s\n\n", be.what()); } try { try { internalTestBaseException(); - } catch (BaseException *be2) { + } catch (BaseException& be2) { THROW_BASE_EXCEPTION_CAUSE("exception 2", be2); } - } catch (BaseException *be) { - std::string str; - be->toString(str); - printf("\n\n%s\n\n", str.c_str()); - delete be; + } catch (BaseException& be) { + printf("\n\n%s\n\n", be.what()); } printf("PASSED\n");