示例#1
0
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();
}
示例#2
0
// 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");
      }
   }
}