void Exception::append(const Exception &another, size_t startDepth) throw() { Exception base; if (this == &another) { base.append(another, startDepth); append(base, 0); return; } size_t baseEntryCount = 0; if (!isEmpty()) { assert(base.isEmpty()); base.append(*this, 0); baseEntryCount = 1 + base.maxDepth_; clear(); } size_t subEntryCount = baseEntryCount + (another.maxDepth_ - startDepth); if (subEntryCount > 0) { subEntries_ = static_cast<Entry*>(allocate(sizeof(Entry) * subEntryCount)); if (subEntries_ == NULL) { subEntryCount = 0; } } maxDepth_ = subEntryCount; for (size_t i = 0; i <= subEntryCount; i++) { Entry &dest = (i > 0 ? subEntries_[i - 1] : topEntry_); const Entry *src; if (i < baseEntryCount) { src = base.getEntryAt(i); } else { src = another.getEntryAt(startDepth + (i - baseEntryCount)); } setEntry(dest, *src); } fillWhat(); }
Exception::Exception( const NamedErrorCode &namedErrorCode, const char8_t *message, const SourceSymbolChar *fileNameLiteral, const SourceSymbolChar *functionNameLiteral, int32_t lineNumber, const std::exception *causeInHandling, const char8_t *typeNameLiteral, StackTraceMode stackTraceMode, DuplicatedLiteralFlags literalFlags) throw() : bufferOffset_(0), subEntries_(NULL), maxDepth_(0), topEntry_(), what_(NULL) { do { #ifdef UTIL_STACK_TRACE_ENABLED if (causeInHandling == NULL && stackTraceMode == STACK_TRACE_TOP) { try { char8_t buf[512]; detail::LocalString str(buf, sizeof(buf)); detail::StackTraceStringHandler handler(str); StackTraceUtils::getStackTrace(handler); setEntry(topEntry_, namedErrorCode, message, str.tryGet(), typeNameLiteral, fileNameLiteral, functionNameLiteral, lineNumber, literalFlags); break; } catch (...) { } } #endif setEntry(topEntry_, namedErrorCode, message, NULL, typeNameLiteral, fileNameLiteral, functionNameLiteral, lineNumber, literalFlags); } while (false); if (causeInHandling != NULL) { Exception *fullEx; std::exception *stdEx; const char8_t *causeType = resolveException(&fullEx, &stdEx); size_t subEntryCount = (fullEx == NULL ? 1 : fullEx->maxDepth_ + 1); subEntries_ = static_cast<Entry*>(allocate(sizeof(Entry) * subEntryCount)); if (subEntries_ == NULL) { subEntryCount = 0; } maxDepth_ = subEntryCount; if (fullEx == NULL) { if (subEntryCount > 0) { const char8_t *causeMessage = NULL; if (stdEx != NULL) { try { causeMessage = stdEx->what(); } catch (...) { } } setEntry(subEntries_[0], NamedErrorCode(), causeMessage, NULL, causeType, NULL, NULL, -1, LITERAL_NORMAL); } } else { for (size_t i = 0; i < subEntryCount; i++) { Entry &dest = subEntries_[i]; const Entry *src = fullEx->getEntryAt(i); setEntry(dest, *src); } } } fillWhat(); }