int ZMQPollData::add(const Variant& entry, int64_t events) { assert(php_items.size() == items.size()); if (!entry.isObject() && !entry.isResource()) { return PHP_ZMQ_POLLSET_ERR_INVALID_TYPE; } auto key = ZMQPollData::createKey(entry); if (!key.length() || key.length() > 34) { return PHP_ZMQ_POLLSET_ERR_KEY_FAIL; } for (int i = 0; i < php_items.size(); i++) { if (php_items[i].key == key) { items[i].events = events; php_items[i].events = events; return i; } } zmq_pollitem_t item{}; item.events = events; if (entry.isResource()) { auto f = cast<File>(entry); item.fd = f->fd(); php_items.push_back(ZMQPollItem(events, entry, key, item.fd)); } else { auto sock = Native::data<ZMQSocket>(entry.asCObjRef()); item.socket = sock->socket->z_socket; php_items.push_back(ZMQPollItem(events, entry, key, item.socket)); } items.push_back(item); return items.size() - 1; }
void HHVM_METHOD(ZMQDevice, __construct, const Object& frontend, const Object& backend, const Variant& capture) { auto dev = Native::data<ZMQDevice>(this_); dev->front = frontend; dev->back = backend; if (!capture.isNull()) { dev->capture = capture.asCObjRef(); } }
String HHVM_METHOD(ZMQPoll, add, const Variant& obj, int64_t events) { auto poll = Native::data<ZMQPoll>(this_); switch (obj.getType()) { case DataType::KindOfObject: if (!obj.asCObjRef().instanceof(s_ZMQSocketClass)) { throwExceptionClass(s_ZMQPollExceptionClass, "The first argument must be an instance of ZMQSocket or a resource", PHP_ZMQ_INTERNAL_ERROR); } break; case DataType::KindOfResource: break; default: throwExceptionClass(s_ZMQPollExceptionClass, "The first argument must be an instance of ZMQSocket or a resource", PHP_ZMQ_INTERNAL_ERROR); } int pos = poll->set.add(obj, events); if (pos < 0) { const char* message = nullptr; switch (pos) { case PHP_ZMQ_POLLSET_ERR_NO_STREAM: message = "The supplied resource is not a valid stream resource"; break; case PHP_ZMQ_POLLSET_ERR_CANNOT_CAST: message = "The supplied resource is not castable"; break; case PHP_ZMQ_POLLSET_ERR_CAST_FAILED: message = "Failed to cast the supplied stream resource"; break; case PHP_ZMQ_POLLSET_ERR_NO_INIT: message = "The ZMQSocket object has not been initialized properly"; break; case PHP_ZMQ_POLLSET_ERR_NO_POLL: message = "The ZMQSocket object has not been initialized with polling"; break; default: message = "Unknown error"; break; } throwExceptionClass(s_ZMQPollExceptionClass, message, PHP_ZMQ_INTERNAL_ERROR); } String ret; if (!poll->set.getKey(pos, ret)) { throwExceptionClass(s_ZMQPollExceptionClass, "Failed to get the item key", PHP_ZMQ_INTERNAL_ERROR); } return ret; }
String ZMQPollData::createKey(const Variant& val) { if (val.isResource()) { char tmp[35]; int tmpLen = snprintf(tmp, 35, "r:%d", val.asCResRef().toInt32()); return String(tmp, tmpLen, CopyString); } else { assert(val.isObject()); return HHVM_FN(spl_object_hash)(val.asCObjRef()); } }
bool HHVM_METHOD(ZMQPoll, remove, const Variant& item) { auto poll = Native::data<ZMQPoll>(this_); if (poll->set.items.size() == 0) { throwExceptionClass(s_ZMQPollExceptionClass, "No sockets assigned to the ZMQPoll", PHP_ZMQ_INTERNAL_ERROR); } switch (item.getType()) { case DataType::KindOfObject: if (!item.asCObjRef().instanceof(s_ZMQSocketClass)) { throwExceptionClass(s_ZMQPollExceptionClass, "The object must be an instance of ZMQSocket", PHP_ZMQ_INTERNAL_ERROR); } /* fallthrough */ case DataType::KindOfResource: return poll->set.erase(item); default: return poll->set.eraseByKey(item.toString()); } }
static void xslt_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) { XSLTProcessorData *intern = nullptr; int error = 0; xsltTransformContextPtr tctxt = xsltXPathGetTransformContext (ctxt); if (tctxt == nullptr) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the transformation context\n" ); error = 1; } else { intern = (XSLTProcessorData*)tctxt->_private; if (intern == nullptr) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the internal object\n" ); error = 1; } else { if (intern->m_registerPhpFunctions == 0) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: PHP Object did not register PHP functions\n" ); error = 1; } } } xmlXPathObjectPtr obj; if (error == 1) { for (int i = nargs - 1; i >= 0; i--) { obj = valuePop(ctxt); xmlXPathFreeObject(obj); } return; } Array args; // Reverse order to pop values off ctxt stack for (int i = nargs - 2; i >= 0; i--) { Variant arg; obj = valuePop(ctxt); switch (obj->type) { case XPATH_STRING: arg = String((char*)obj->stringval, CopyString); break; case XPATH_BOOLEAN: arg = (bool)obj->boolval; break; case XPATH_NUMBER: arg = (double)obj->floatval; break; case XPATH_NODESET: if (type == 1) { char *str = (char*)xmlXPathCastToString(obj); arg = String(str, CopyString); xmlFree(str); } else if (type == 2) { arg = Array::Create(); if (obj->nodesetval && obj->nodesetval->nodeNr > 0) { for (int j = 0; j < obj->nodesetval->nodeNr; j++) { // TODO: not sure this is the right thing to do. xmlNodePtr node = obj->nodesetval->nodeTab[j]; if (node->type == XML_ELEMENT_NODE) { Object element = newNode(s_DOMElement, xmlCopyNode(node, /*extended*/ 1)); arg.toArrRef().append(element); } else if (node->type == XML_ATTRIBUTE_NODE) { Object attribute = newNode(s_DOMAttr, (xmlNodePtr)xmlCopyProp(nullptr, (xmlAttrPtr)node)); arg.toArrRef().append(attribute); } else if (node->type == XML_TEXT_NODE) { Object text = newNode(s_DOMText, (xmlNodePtr)xmlNewText(xmlNodeGetContent(node))); arg.toArrRef().append(text); } else { raise_warning("Unhandled node type '%d'", node->type); // Use a generic DOMNode as fallback for now. Object nodeobj = newNode(s_DOMNode, xmlCopyNode(node, /*extended*/ 1)); arg.toArrRef().append(nodeobj); } } } } break; default: arg = String((char*)xmlXPathCastToString(obj), CopyString); } xmlXPathFreeObject(obj); args.prepend(arg); } obj = valuePop(ctxt); if (obj->stringval == nullptr) { raise_warning("Handler name must be a string"); xmlXPathFreeObject(obj); // Push an empty string to get an xslt result. valuePush(ctxt, xmlXPathNewString((xmlChar*)"")); return; } String handler((char*)obj->stringval, CopyString); xmlXPathFreeObject(obj); if (!HHVM_FN(is_callable)(handler)) { raise_warning("Unable to call handler %s()", handler.data()); // Push an empty string to get an xslt result. valuePush(ctxt, xmlXPathNewString((xmlChar*)"")); } else if (intern->m_registerPhpFunctions == 2 && !intern->m_registered_phpfunctions.exists(handler)) { raise_warning("Not allowed to call handler '%s()'", handler.data()); // Push an empty string to get an xslt result. valuePush(ctxt, xmlXPathNewString((xmlChar*)"")); } else { Variant retval = vm_call_user_func(handler, args); if (retval.isObject() && retval.getObjectData()->instanceof(s_DOMNode)) { ObjectData *retval_data = retval.asCObjRef().get(); xmlNode* nodep = Native::data<DOMNode>(retval_data)->nodep(); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); intern->m_usedElements.prepend(retval); } else if (retval.is(KindOfBoolean)) { valuePush(ctxt, xmlXPathNewBoolean(retval.toBoolean())); } else if (retval.isObject()) { raise_warning("A PHP Object cannot be converted to an XPath-string"); // Push an empty string to get an xslt result. valuePush(ctxt, xmlXPathNewString((xmlChar*)"")); } else { String sretval = retval.toString(); valuePush(ctxt, xmlXPathNewString((xmlChar*)sretval.data())); } } }