static const QoreStringNode* get_string_header_node(ExceptionSink* xsink, QoreHashNode& h, const char* header, bool allow_multiple = false) { AbstractQoreNode* n = h.getKeyValue(header); if (!n) return 0; qore_type_t t = get_node_type(n); if (t == NT_STRING) return reinterpret_cast<const QoreStringNode*>(n); assert(t == NT_LIST); if (!allow_multiple) { xsink->raiseException("HTTP-HEADER-ERROR", "multiple \"%s\" headers received in HTTP message", header); return 0; } // convert list to a comma-separated string QoreListNode* l = reinterpret_cast<QoreListNode*>(n); // get first list entry n = l->retrieve_entry(0); assert(get_node_type(n) == NT_STRING); QoreStringNode* rv = reinterpret_cast<QoreStringNode*>(n)->copy(); for (size_t i = 1; i < l->size(); ++i) { n = l->retrieve_entry(i); assert(get_node_type(n) == NT_STRING); rv->concat(','); rv->concat(reinterpret_cast<QoreStringNode*>(n)); } // dereference old list and save reference to return value in header hash h.setKeyValue(header, rv, xsink); return rv; }
AbstractQoreNode* QoreXmlReader::getXmlData(ExceptionSink* xsink, const QoreEncoding* data_ccsid, int pflags, int min_depth) { xml_stack xstack; QORE_TRACE("getXMLData()"); int rc = 1; while (rc == 1) { int nt = nodeTypeSkipWhitespace(); // get node name const char* name = constName(); if (!name) name = "--"; if (nt == -1) // ERROR break; if (nt == XML_READER_TYPE_ELEMENT) { int depth = QoreXmlReader::depth(); xstack.checkDepth(depth); AbstractQoreNode* n = xstack.getNode(); // if there is no node pointer, then make a hash if (!n) { QoreHashNode* h = new QoreHashNode; xstack.setNode(h); xstack.push(h->getKeyValuePtr(name), depth); } else { // node ptr already exists QoreHashNode* h = n->getType() == NT_HASH ? reinterpret_cast<QoreHashNode*>(n) : 0; if (!h) { h = new QoreHashNode; xstack.setNode(h); h->setKeyValue("^value^", n, 0); xstack.incValueCount(); xstack.push(h->getKeyValuePtr(name), depth); } else { // see if key already exists AbstractQoreNode* v; bool exists; v = h->getKeyValueExistence(name, exists); if (!exists) xstack.push(h->getKeyValuePtr(name), depth); else { if (!(pflags & XPF_PRESERVE_ORDER)) { QoreListNode* vl = get_node_type(v) == NT_LIST ? reinterpret_cast<QoreListNode*>(v) : 0; // if it's not a list, then make into a list with current value as first entry if (!vl) { AbstractQoreNode** vp = h->getKeyValuePtr(name); vl = new QoreListNode; vl->push(v); (*vp) = vl; } xstack.push(vl->get_entry_ptr(vl->size()), depth); } else { // see if last key was the same, if so make a list if it's not const char* lk = h->getLastKey(); bool get_value = false; if (keys_are_equal(name, lk, get_value)) { // get actual key value if there was a suffix if (get_value) v = h->getKeyValue(lk); QoreListNode* vl = get_node_type(v) == NT_LIST ? reinterpret_cast<QoreListNode*>(v) : 0; // if it's not a list, then make into a list with current value as first entry if (!vl) { AbstractQoreNode** vp = h->getKeyValuePtr(lk); vl = new QoreListNode; vl->push(v); (*vp) = vl; } xstack.push(vl->get_entry_ptr(vl->size()), depth); } else { QoreString ns; int c = 1; while (true) { ns.sprintf("%s^%d", name, c); if (!h->existsKey(ns.getBuffer())) break; c++; ns.clear(); } xstack.push(h->getKeyValuePtr(ns.getBuffer()), depth); } } } } } // add attributes to structure if possible if (hasAttributes()) { ReferenceHolder<QoreHashNode> h(new QoreHashNode, xsink); while (moveToNextAttribute(xsink) == 1) { const char* aname = constName(); QoreStringNode* value = getValue(data_ccsid, xsink); if (!value) return 0; h->setKeyValue(aname, value, xsink); } if (*xsink) return 0; // make new new a hash and assign "^attributes^" key QoreHashNode* nv = new QoreHashNode; nv->setKeyValue("^attributes^", h.release(), xsink); xstack.setNode(nv); } //printd(5, "%s: type: %d, hasValue: %d, empty: %d, depth: %d\n", name, nt, xmlTextReaderHasValue(reader), xmlTextReaderIsEmptyElement(reader), depth); } else if (nt == XML_READER_TYPE_TEXT) { int depth = QoreXmlReader::depth(); xstack.checkDepth(depth); const char* str = constValue(); if (str) { QoreStringNodeHolder val(getValue(data_ccsid, xsink)); if (!val) return 0; AbstractQoreNode* n = xstack.getNode(); if (n) { QoreHashNode* h = n->getType() == NT_HASH ? reinterpret_cast<QoreHashNode*>(n) : 0; if (h) { if (!xstack.getValueCount()) h->setKeyValue("^value^", val.release(), xsink); else { QoreString kstr; kstr.sprintf("^value%d^", xstack.getValueCount()); h->setKeyValue(kstr.getBuffer(), val.release(), xsink); } } else { // convert value to hash and save value node h = new QoreHashNode; xstack.setNode(h); h->setKeyValue("^value^", n, 0); xstack.incValueCount(); QoreString kstr; kstr.sprintf("^value%d^", 1); h->setKeyValue(kstr.getBuffer(), val.release(), xsink); } xstack.incValueCount(); } else xstack.setNode(val.release()); } } else if (nt == XML_READER_TYPE_CDATA) { int depth = QoreXmlReader::depth(); xstack.checkDepth(depth); const char* str = constValue(); if (str) { QoreStringNode* val = getValue(data_ccsid, xsink); if (!val) return 0; AbstractQoreNode* n = xstack.getNode(); if (n && n->getType() == NT_HASH) { QoreHashNode* h = reinterpret_cast<QoreHashNode*>(n); if (!xstack.getCDataCount()) h->setKeyValue("^cdata^", val, xsink); else { QoreString kstr; kstr.sprintf("^cdata%d^", xstack.getCDataCount()); h->setKeyValue(kstr.getBuffer(), val, xsink); } } else { // convert value to hash and save value node QoreHashNode* h = new QoreHashNode; xstack.setNode(h); if (n) { h->setKeyValue("^value^", n, 0); xstack.incValueCount(); } h->setKeyValue("^cdata^", val, xsink); } xstack.incCDataCount(); } } rc = read(); if (min_depth > 0 && QoreXmlReader::depth() < min_depth) { rc = 0; break; } } return rc ? 0 : xstack.getVal(); }
// static member function void ExceptionSink::defaultExceptionHandler(QoreException* e) { ExceptionSink xsink; QoreString nstr; { DateTime now; now.setNow(); now.format(nstr, "YYYY-MM-DD HH:mm:SS.xx Dy Z (z)"); } unsigned ecnt = 0; while (e) { //printd(5, "ExceptionSink::defaultExceptionHandler() cs size=%d\n", cs->size()); printe("unhandled QORE %s exception thrown in TID %d at %s", e->type == ET_USER ? "User" : "System", gettid(), nstr.getBuffer()); QoreListNode *cs = e->callStack; bool found = false; if (cs->size()) { // find first non-rethrow element unsigned i = 0; QoreHashNode *h; while (true) { h = reinterpret_cast<QoreHashNode *>(cs->retrieve_entry(i)); assert(h); if ((reinterpret_cast<QoreBigIntNode *>(h->getKeyValue("typecode")))->val != CT_RETHROW) break; i++; if (i == cs->size()) break; } if (i < cs->size()) { found = true; QoreStringNode *func = reinterpret_cast<QoreStringNode *>(h->getKeyValue("function")); QoreStringNode *type = reinterpret_cast<QoreStringNode *>(h->getKeyValue("type")); printe(" in %s() (%s:%d", func->getBuffer(), e->file.c_str(), e->start_line); if (e->start_line == e->end_line) { if (!e->source.empty()) printe(", source %s:%d", e->source.c_str(), e->start_line + e->offset); } else { printe("-%d", e->end_line); if (!e->source.empty()) printe(", source %s:%d-%d", e->source.c_str(), e->start_line + e->offset, e->end_line + e->offset); } printe(", %s code)\n", type->getBuffer()); } } if (!found) { if (!e->file.empty()) { printe(" at %s:", e->file.c_str()); if (e->start_line == e->end_line) { if (!e->start_line) { printe("<init>"); if (!e->source.empty()) printe(" (source %s)", e->source.c_str()); } else { printe("%d", e->start_line); if (!e->source.empty()) printe(" (source %s:%d)", e->source.c_str(), e->start_line + e->offset); } } else { printe("%d-%d", e->start_line, e->end_line); if (!e->source.empty()) printe(" (source %s:%d-%d)", e->source.c_str(), e->start_line + e->offset, e->end_line + e->offset); } } else if (e->start_line) { if (e->start_line == e->end_line) { if (!e->start_line) printe(" at <init>"); else printe(" on line %d", e->start_line); } else printe(" on lines %d through %d", e->start_line, e->end_line); } printe("\n"); } if (e->type == ET_SYSTEM) { QoreStringNode* err = reinterpret_cast<QoreStringNode *>(e->err); QoreStringNode* desc = reinterpret_cast<QoreStringNode *>(e->desc); printe("%s: %s\n", err->getBuffer(), desc->getBuffer()); } else { bool hdr = false; if (e->err) { if (e->err->getType() == NT_STRING) { QoreStringNode *err = reinterpret_cast<QoreStringNode *>(e->err); printe("%s", err->getBuffer()); } else { QoreNodeAsStringHelper str(e->err, FMT_NORMAL, &xsink); printe("EXCEPTION: %s", str->getBuffer()); hdr = true; } } else printe("EXCEPTION"); if (e->desc) { if (e->desc->getType() == NT_STRING) { QoreStringNode *desc = reinterpret_cast<QoreStringNode *>(e->desc); printe("%s%s", hdr ? ", desc: " : ": ", desc->getBuffer()); } else { QoreNodeAsStringHelper str(e->desc, FMT_NORMAL, &xsink); printe(", desc: %s", str->getBuffer()); hdr = true; } } if (e->arg) { if (e->arg->getType() == NT_STRING) { QoreStringNode *arg = reinterpret_cast<QoreStringNode *>(e->arg); printe("%s%s", hdr ? ", arg: " : "", arg->getBuffer()); } else { QoreNodeAsStringHelper str (e->arg, FMT_NORMAL, &xsink); printe(", arg: %s", str->getBuffer()); } } printe("\n"); } if (cs->size()) { printe("call stack:\n"); for (unsigned i = 0; i < cs->size(); i++) { int pos = cs->size() - i; QoreHashNode* h = reinterpret_cast<QoreHashNode*>(cs->retrieve_entry(i)); QoreStringNode* strtype = reinterpret_cast<QoreStringNode*>(h->getKeyValue("type")); const char* type = strtype->getBuffer(); int typecode = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("typecode"))->val; if (!strcmp(type, "new-thread")) printe(" %2d: *thread start*\n", pos); else { QoreStringNode* fn = reinterpret_cast<QoreStringNode*>(h->getKeyValue("file")); const char* fns = fn && !fn->empty() ? fn->getBuffer() : 0; int start_line = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("line"))->val; int end_line = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("endline"))->val; QoreStringNode* src = reinterpret_cast<QoreStringNode*>(h->getKeyValue("source")); const char* srcs = src && !src->empty() ? src->getBuffer() : 0; int offset = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("offset"))->val; printe(" %2d: ", pos); if (typecode == CT_RETHROW) { printe("RETHROW at "); if (fn) { printe("%s:", fn->getBuffer()); } else printe("line"); printe("%d", start_line); if (srcs) printe(" (source %s:%d)", srcs, offset + start_line); } else { QoreStringNode* fs = reinterpret_cast<QoreStringNode *>(h->getKeyValue("function")); printe("%s() (", fs->getBuffer()); if (fns) { if (start_line == end_line) { if (!start_line) printe("%s:<init>", fns); else { printe("%s:%d", fns, start_line); if (srcs) printe(" (source %s:%d)", srcs, start_line + offset); } } else { printe("%s:%d-%d", fns, start_line, end_line); if (srcs) printe(" (source %s:%d-%d)", srcs, start_line + offset, end_line + offset); } } else { if (start_line == end_line) { if (!start_line) printe("<init>"); else printe("line %d", start_line); } else printe("line %d - %d", start_line, end_line); } printe(", %s code)", type); } printe("\n"); } } } e = e->next; if (e) { ++ecnt; if (ecnt == Q_MAX_EXCEPTIONS) { printe("*** maximum exception count reached (%d); supressing further output\n", ecnt); break; } printe("chained exception:\n"); } } }