00001
00015 #include <cstdarg>
00016 #include <cstdio>
00017 #include <cstring>
00018 #include <stdexcept>
00019 #include <dlrCommon/exception.h>
00020
00021
00022 namespace {
00023
00024
00025
00026
00027 int l_snprintf(char* targetPtr, size_t targetSize,
00028 const char* formatPtr, ...) {
00029 char workingBuffer[1024];
00030 va_list varArgsList;
00031 va_start(varArgsList, formatPtr);
00032
00033 const char* workingFormatPtr = formatPtr;
00034 char* workingTargetPtr = targetPtr;
00035 size_t spaceLeft = targetSize - 1;
00036
00037
00038 while(spaceLeft && (*workingFormatPtr != '\0')) {
00039 int intValue;
00040 double doubleValue;
00041 char* charPtrValue;
00042 size_t stringSize;
00043 if(*workingFormatPtr == '%') {
00044 ++workingFormatPtr;
00045 switch(*workingFormatPtr) {
00046 case '\0':
00047 break;
00048 case 'd':
00049 intValue = va_arg(varArgsList, int);
00050 sprintf(workingBuffer, "%d", intValue);
00051 std::strncpy(workingTargetPtr, workingBuffer, spaceLeft);
00052 stringSize = strlen(workingBuffer);
00053 workingTargetPtr +=
00054 (stringSize > spaceLeft) ? spaceLeft : stringSize;
00055 spaceLeft -= (stringSize > spaceLeft) ? spaceLeft : stringSize;
00056 ++workingFormatPtr;
00057 break;
00058 case 'f':
00059 doubleValue = va_arg(varArgsList, double);
00060 sprintf(workingBuffer, "%f", doubleValue);
00061 std::strncpy(workingTargetPtr, workingBuffer, spaceLeft);
00062 stringSize = strlen(workingBuffer);
00063 workingTargetPtr +=
00064 (stringSize > spaceLeft) ? spaceLeft : stringSize;
00065 spaceLeft -= (stringSize > spaceLeft) ? spaceLeft : stringSize;
00066 ++workingFormatPtr;
00067 break;
00068 case 's':
00069 charPtrValue = va_arg(varArgsList, char*);
00070 std::strncpy(workingTargetPtr, charPtrValue, spaceLeft);
00071 stringSize = strlen(charPtrValue);
00072 workingTargetPtr +=
00073 (stringSize > spaceLeft) ? spaceLeft : stringSize;
00074 spaceLeft -= (stringSize > spaceLeft) ? spaceLeft : stringSize;
00075 ++workingFormatPtr;
00076 break;
00077 default:
00078 va_end(varArgsList);
00079 std::sprintf(
00080 workingBuffer,
00081 "Exception(l_snprintf()): Format string %%%c not recognized.",
00082 *workingFormatPtr);
00083 throw std::invalid_argument(workingBuffer);
00084 }
00085 } else {
00086 *workingTargetPtr++ = *workingFormatPtr++;
00087 --spaceLeft;
00088 }
00089 }
00090 if(targetSize > 0) {
00091 *workingTargetPtr = '\0';
00092 }
00093 va_end(varArgsList);
00094 return static_cast<int>(workingTargetPtr - targetPtr);
00095 }
00096
00097 }
00098
00099
00100 namespace dlr {
00101
00102 namespace common {
00103
00104
00105 Exception::
00106 Exception(const char* message)
00107 throw()
00108 : std::exception(),
00109 m_traceMessage(),
00110 m_traceMessageIndex(0)
00111 {
00112 l_snprintf(m_message, DLR_EXCEPTION_MESSAGE_LENGTH, "Exception: %s",
00113 message);
00114 m_traceMessage[0] = '\0';
00115 }
00116
00117
00118
00119 Exception::
00120 Exception(const char* message, const char* fileName, int lineNumber)
00121 throw()
00122 : std::exception(),
00123 m_traceMessage(),
00124 m_traceMessageIndex(0)
00125 {
00126 l_snprintf(m_message, DLR_EXCEPTION_MESSAGE_LENGTH,
00127 "Exception(%s, %d): %s",
00128 fileName, lineNumber, message);
00129 m_traceMessage[0] = '\0';
00130 }
00131
00132
00133
00134 Exception::
00135 Exception(const char* message, const char* functionName,
00136 const char* fileName, int lineNumber)
00137 throw()
00138 : std::exception(),
00139 m_traceMessage(),
00140 m_traceMessageIndex(0)
00141 {
00142 l_snprintf(m_message, DLR_EXCEPTION_MESSAGE_LENGTH,
00143 "Exception(%s, %s, %d): %s",
00144 functionName, fileName, lineNumber, message);
00145 m_traceMessage[0] = '\0';
00146 }
00147
00148
00149
00150 Exception::
00151 Exception(const Exception& source)
00152 throw()
00153 : std::exception(),
00154 m_traceMessage(),
00155 m_traceMessageIndex(source.m_traceMessageIndex)
00156 {
00157 strncpy(m_message, source.m_message, DLR_EXCEPTION_MESSAGE_LENGTH);
00158 m_message[DLR_EXCEPTION_MESSAGE_LENGTH - 1] = '\0';
00159
00160 size_t traceMessageMaxLength =
00161 (DLR_EXCEPTION_TRACE_REQUIRED_STACK_LEVELS
00162 * DLR_EXCEPTION_TRACE_MESSAGE_LENGTH);
00163 strncpy(m_traceMessage, source.m_traceMessage, traceMessageMaxLength);
00164 m_traceMessage[traceMessageMaxLength - 1] = '\0';
00165 }
00166
00167
00168
00169 Exception& Exception::
00170 operator=(const Exception& source)
00171 throw()
00172 {
00173 strncpy(m_message, source.m_message, DLR_EXCEPTION_MESSAGE_LENGTH);
00174 m_message[DLR_EXCEPTION_MESSAGE_LENGTH - 1] = '\0';
00175
00176 size_t traceMessageMaxLength =
00177 (DLR_EXCEPTION_TRACE_REQUIRED_STACK_LEVELS
00178 * DLR_EXCEPTION_TRACE_MESSAGE_LENGTH);
00179 strncpy(m_traceMessage, source.m_traceMessage, traceMessageMaxLength);
00180 m_traceMessage[traceMessageMaxLength - 1] = '\0';
00181
00182 m_traceMessageIndex = source.m_traceMessageIndex;
00183
00184 return *this;
00185 }
00186
00187
00188
00189 Exception::
00190 Exception(const char* message, const char* childClassName)
00191 throw()
00192 : std::exception(),
00193 m_traceMessage(),
00194 m_traceMessageIndex(0)
00195 {
00196 l_snprintf(m_message, DLR_EXCEPTION_MESSAGE_LENGTH, "%s: %s",
00197 childClassName, message);
00198 m_traceMessage[0] = '\0';
00199 }
00200
00201
00202
00203 Exception::
00204 Exception(const char* message, const char* childClassName,
00205 const char* functionName, const char* fileName,
00206 int lineNumber)
00207 throw()
00208 : std::exception(),
00209 m_traceMessage(),
00210 m_traceMessageIndex(0)
00211 {
00212 if(functionName == 0) {
00213 l_snprintf(m_message, DLR_EXCEPTION_MESSAGE_LENGTH,
00214 "%s(%s, %d): %s",
00215 childClassName, fileName, lineNumber, message);
00216 } else {
00217 l_snprintf(m_message, DLR_EXCEPTION_MESSAGE_LENGTH,
00218 "%s(%s, %s, %d): %s",
00219 childClassName, functionName, fileName, lineNumber,
00220 message);
00221 }
00222 m_traceMessage[0] = '\0';
00223 }
00224
00225
00226
00227
00228 void
00229 Exception::
00230 addTrace(const char* message)
00231 throw()
00232 {
00233 const char* ellipsisString = "...";
00234 size_t ellipsisLength = strlen(ellipsisString);
00235
00236
00237 if(DLR_EXCEPTION_TRACE_MESSAGE_LENGTH < (ellipsisLength + 1)) {
00238 return;
00239 }
00240
00241 if(message != 0) {
00242
00243 bool useEllipsis = false;
00244
00245
00246 size_t messageLength = std::strlen(message);
00247 if(messageLength >= DLR_EXCEPTION_TRACE_MESSAGE_LENGTH) {
00248 messageLength = DLR_EXCEPTION_TRACE_MESSAGE_LENGTH - 1;
00249 useEllipsis = true;
00250 }
00251
00252
00253 size_t remainingSpace =
00254 (DLR_EXCEPTION_TRACE_REQUIRED_STACK_LEVELS
00255 * DLR_EXCEPTION_TRACE_MESSAGE_LENGTH) - m_traceMessageIndex;
00256 if((messageLength + 1) > remainingSpace) {
00257
00258
00259 m_traceMessageIndex = (DLR_EXCEPTION_TRACE_REQUIRED_STACK_LEVELS
00260 * DLR_EXCEPTION_TRACE_MESSAGE_LENGTH);
00261 return;
00262 }
00263
00264
00265
00266 if(useEllipsis) {
00267
00268 if(messageLength < ellipsisLength) {
00269 return;
00270 }
00271 messageLength -= ellipsisLength;
00272 }
00273
00274
00275
00276 std::strncpy(
00277 m_traceMessage + m_traceMessageIndex, message, messageLength);
00278 m_traceMessageIndex += messageLength;
00279
00280
00281
00282
00283 if(useEllipsis) {
00284
00285 std::strcpy(m_traceMessage + m_traceMessageIndex, ellipsisString);
00286 m_traceMessageIndex += strlen(ellipsisString);
00287 } else {
00288 m_traceMessage[m_traceMessageIndex] = '\0';
00289 }
00290 }
00291 }
00292
00293 }
00294
00295 }