示例#1
0
static void
exsltMathMaxFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlNodeSetPtr ns;
    double ret;
    void *user = NULL;

    if (nargs != 1) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    
    if ((ctxt->value != NULL) && (ctxt->value->boolval != 0)) {
	user = ctxt->value->user;
	ctxt->value->boolval = 0;
	ctxt->value->user = 0;
    }
    ns = xmlXPathPopNodeSet(ctxt);
    if (xmlXPathCheckError(ctxt))
	return;

    ret = exsltMathMax(ns);

    xmlXPathFreeNodeSet(ns);

    if (user != NULL)
        xmlFreeNodeList((xmlNodePtr)user);
    xmlXPathReturnNumber(ctxt, ret);
}
示例#2
0
/**
 * exsltMathLowestFunction:
 * @ctxt:  an XPath parser context
 * @nargs:  the number of arguments
 *
 * Wraps #exsltMathLowest for use by the XPath processor
 */
static void
exsltMathLowestFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlNodeSetPtr ns, ret;
    void *user = NULL;
    

    if (nargs != 1) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    /* We need to delay the freeing of value->user */
    if ((ctxt->value != NULL) && (ctxt->value->boolval != 0)) {
        user = ctxt->value->user;
	ctxt->value->boolval = 0;
	ctxt->value->user = NULL;
    }
    ns = xmlXPathPopNodeSet(ctxt);
    if (xmlXPathCheckError(ctxt))
	return;

    ret = exsltMathLowest(ns);

    xmlXPathFreeNodeSet(ns);
    if (user != NULL)
        xmlFreeNodeList((xmlNodePtr)user);

    xmlXPathReturnNodeSet(ctxt, ret);
}
示例#3
0
/**
 * exsltMathMinFunction:
 * @ctxt:  an XPath parser context
 * @nargs:  the number of arguments
 *
 * Wraps #exsltMathMin for use by the XPath processor.
 */
static void
exsltMathMinFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlNodeSetPtr ns;
    double ret;
    void *user = NULL;

    if (nargs != 1) {
	xsltGenericError(xsltGenericErrorContext,
			 "math:min: invalid number of arguments\n");
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    /* We need to delay the freeing of value->user */
    if ((ctxt->value != NULL) && (ctxt->value->boolval != 0)) {
        user = ctxt->value->user;
	ctxt->value->boolval = 0;
	ctxt->value->user = NULL;
    }
    ns = xmlXPathPopNodeSet(ctxt);
    if (xmlXPathCheckError(ctxt))
	return;

    ret = exsltMathMin(ns);

    xmlXPathFreeNodeSet(ns);
    if (user != NULL)
        xmlFreeNodeList((xmlNodePtr)user);

    xmlXPathReturnNumber(ctxt, ret);
}
示例#4
0
/**
 * xmlSecNodeSetDestroy:
 * @nset: 		the pointer to node set.
 *
 * Destroys the nodes set created with #xmlSecNodeSetCreate function.
 */
EXPORT_C
void
xmlSecNodeSetDestroy(xmlSecNodeSetPtr nset) {
    xmlSecNodeSetPtr tmp;

    xmlSecAssert(nset != NULL);
    	
    while((tmp = nset) != NULL) {
	if((nset->next != NULL) && (nset->next != nset)) {
	    nset->next->prev = nset->prev;
	    nset->prev->next = nset->next;	    
	    nset = nset->next;
	} else {
	    nset = NULL;
	}
	
	if(tmp->nodes != NULL) {
    	    xmlXPathFreeNodeSet(tmp->nodes);
	}
	if(tmp->children != NULL) {
	    xmlSecNodeSetDestroy(tmp->children);
	}
	if((tmp->doc != NULL) && (tmp->destroyDoc != 0)) {
	    xmlFreeDoc(tmp->doc);
	}
	memset(tmp, 0,  sizeof(xmlSecNodeSet));
        xmlFree(tmp);
    }
}
示例#5
0
/** @arg n entry node
 * @arg len size of @a *s in bytes
 * @arg s pointer where result will be saved, error string on failure
 * @retval TRUE on success
 * @retval FALSE on error
 */
gboolean entry_orths_to_string(xmlNodePtr n, int len, char *s)
{
  g_return_val_if_fail(n, FALSE);
  g_return_val_if_fail(s, FALSE);
  g_return_val_if_fail(len>0, FALSE);

  xmlDocPtr doc = copy_node_to_doc(n);

  // find the orth children of the current entry
  xmlNodeSetPtr set = find_node_set("/entry/form/orth", doc, NULL);

  if(!set || !set->nodeNr)
  {
    g_strlcpy(s, _("No nodes (form/orth)!"), len);
    if(set) xmlXPathFreeNodeSet(set);
    xmlFreeDoc(doc);
    return FALSE;
  }

  // alloc temporary buffer
  // if glib offered g_utf8_strlcat(), we would not need
  // this buffer
  char *e = (char *) g_malloc(len);
  e[0] = '\0';

  int i;
  xmlNodePtr *n2;
  for(i=0, n2 = set->nodeTab; *n2 && i<set->nodeNr; n2++, i++)
  {
    xmlChar* content = xmlNodeGetContent(*n2);
    int l = strlen(e);
    if(l) g_strlcat(e, ", ", len);
    if(!content) g_strlcat(e, "(null)", len);
    else g_strlcat(e, (gchar *) content, len);
    if(content) xmlFree(content);
  }

  xmlXPathFreeNodeSet(set);

  // copy again, caring for utf8 chars longer than 1 byte
  g_utf8_strncpy(s, e, len/2);

  g_free(e);
  xmlFreeDoc(doc);
  return TRUE;
}
示例#6
0
bool NavigationTable::ParseXML(xmlNodePtr node)
{
    if ( node == nullptr )
        return false;
    
    string name(node->name);
    if ( AllowedRootNodeNames.find(name) == AllowedRootNodeNames.end() )
        return false;
    
    _type = _getProp(node, "type", ePub3NamespaceURI);
    if ( _type.empty() )
        return false;

#if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS)
    XPathWrangler xpath(node->doc, {{"epub", ePub3NamespaceURI}}); // goddamn I love C++11 initializer list constructors
#else
    XPathWrangler::NamespaceList __ns;
    __ns["epub"] = ePub3NamespaceURI;
    XPathWrangler xpath(node->doc, __ns);
#endif
    xpath.NameDefaultNamespace("html");
    
    // look for optional <h2> title
    // Q: Should we fail on finding multiple <h2> tags here?
    auto strings = xpath.Strings("./html:h2[1]/text()", node);
    if ( !strings.empty() )
        _title = std::move(strings[0]);

    
    // load List Elements from a single Ordered List
    // first: confirm there's a single list
    xmlNodeSetPtr nodes = xpath.Nodes("./html:ol", node);
    if ( nodes == nullptr )
        return false;
    if ( nodes->nodeNr != 1 )
    {
        xmlXPathFreeNodeSet(nodes);
        return false;
    }

    LoadChildElements(std::enable_shared_from_this<NavigationTable>::shared_from_this(), nodes->nodeTab[0]);

    xmlXPathFreeNodeSet(nodes);
    
    return true;
}
示例#7
0
xmlNodePtr getXNode(xmlXPathContextPtr context, const gchar *xpath) {
  xmlNodeSetPtr set = getXNodes(context, xpath);
  xmlNodePtr ret = NULL;

  if(!xmlXPathNodeSetIsEmpty(set))
    ret = set->nodeTab[0];

  xmlXPathFreeNodeSet(set);
  return ret;
}
示例#8
0
static int
xmlSecTransformVisa3DHackExecute(xmlSecTransformPtr transform, int last,
                            xmlSecTransformCtxPtr transformCtx) {
    xmlChar** idPtr;
    xmlDocPtr doc;
    xmlAttrPtr attr;
    xmlNodeSetPtr nodeSet;

    xmlSecAssert2(xmlSecTransformVisa3DHackCheckId(transform), -1);
    xmlSecAssert2(transform->outNodes == NULL, -1);
    xmlSecAssert2(last != 0, -1);
    xmlSecAssert2(transformCtx != NULL, -1);

    idPtr = xmlSecVisa3DHackTransformGetIDPtr(transform);
    xmlSecAssert2(idPtr != NULL, -1);
    xmlSecAssert2((*idPtr) != NULL, -1);

    doc = (transform->inNodes != NULL) ? transform->inNodes->doc : transform->hereNode->doc;
    xmlSecAssert2(doc != NULL, -1);

    attr = xmlGetID(doc, (*idPtr));
    if((attr == NULL) || (attr->parent == NULL)) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    "xmlGetID",
                    XMLSEC_ERRORS_R_XML_FAILED,
                    "id=\"%s\"",
                    xmlSecErrorsSafeString((*idPtr)));
        return(-1);
    }

    nodeSet = xmlXPathNodeSetCreate(attr->parent);
    if(nodeSet == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    "xmlXPathNodeSetCreate",
                    XMLSEC_ERRORS_R_XML_FAILED,
                    "id=\"%s\"",
                    xmlSecErrorsSafeString((*idPtr)));
        return(-1);
    }

    transform->outNodes = xmlSecNodeSetCreate(doc, nodeSet, xmlSecNodeSetTreeWithoutComments);
    if(transform->outNodes == NULL) {
        xmlSecError(XMLSEC_ERRORS_HERE,
                    xmlSecErrorsSafeString(xmlSecTransformGetName(transform)),
                    "xmlSecNodeSetCreate",
                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
                    XMLSEC_ERRORS_NO_MESSAGE);
        xmlXPathFreeNodeSet(nodeSet);
        return(-1);
    }
    return(0);
}
示例#9
0
xmlNodePtr find_single_node(const char *xpath, const xmlDocPtr doc)
{
  xmlNodeSetPtr nodes = find_node_set(xpath, doc, NULL);
  if(!nodes) return NULL;
  if(nodes->nodeNr>1)
    g_printerr(_("%s: %i matching nodes (only 1 expected). Taking first.\n"),
      G_STRLOC, nodes->nodeNr);

  xmlNodePtr bodyNode = *(nodes->nodeTab);
  xmlXPathFreeNodeSet(nodes);
  return bodyNode;
}
示例#10
0
bool NavigationTable::Parse(xmlNodePtr node)
{
    if ( node == nullptr )
        return false;
    
    string name(node->name);
    if ( AllowedRootNodeNames.find(name) == AllowedRootNodeNames.end() )
        return false;
    
    _type = _getProp(node, "type", ePub3NamespaceURI);
    if ( _type.empty() )
        return false;
    
    XPathWrangler xpath(node->doc, {{"epub", ePub3NamespaceURI}}); // goddamn I love C++11 initializer list constructors
    xpath.NameDefaultNamespace("html");
    
    // look for optional <h2> title
    // Q: Should we fail on finding multiple <h2> tags here?
    auto strings = xpath.Strings("./html:h2[1]/text()", node);
    if ( !strings.empty() )
        _title = std::move(strings[0]);

    
    // load List Elements from a single Ordered List
    // first: confirm there's a single list
    xmlNodeSetPtr nodes = xpath.Nodes("./html:ol", node);
    if ( nodes == nullptr )
        return false;
    if ( nodes->nodeNr != 1 )
    {
        xmlXPathFreeNodeSet(nodes);
        return false;
    }

    LoadChildElements(this, nodes->nodeTab[0]);

    xmlXPathFreeNodeSet(nodes);
    
    return true;
}
示例#11
0
static void
load_shapefiles()
{
	if (shapefiles || shapefileIds)
		return;

	xmlDoc *doc;
	xmlXPathContext* xpath;

	doc = xmlReadFile(darxen_file_support_get_overridable_file_path("Shapefiles.xml"), NULL, 0);

	if (!doc)
	{
		g_warning("Unable to load default shapefiles");
		return;
	}

	xpath = xmlXPathNewContext(doc);
	if (!xpath)
	{
		xmlFreeDoc(doc);
		g_warning("Unable to load default shapefiles");
		return;
	}

	int idCount;
	char** ids = darxen_xml_get_strs(xpath, "/Shapefiles/Shapefile/@id", &idCount);

	int i;
	for (i = 0; i < idCount; i++)
	{
		shapefileIds = g_slist_prepend(shapefileIds, ids[1]);

		gchar* expr = darxen_xml_path_format("/Shapefiles/Shapefile[@id=\"%s\"]", ids[i]);
		xmlNodeSet* nodes = darxen_xml_get_nodes(xpath, expr);
		g_free(expr);
		g_assert(nodes->nodeNr == 1);

		DarxenShapefile* shapefile = darxen_shapefiles_load_config(nodes->nodeTab[0], NULL);

		shapefiles = g_list_prepend(shapefiles, shapefile);

		xmlXPathFreeNodeSet(nodes);
	}
	free(ids);

	shapefileIds = g_slist_reverse(shapefileIds);
	shapefiles = g_list_reverse(shapefiles);

    xmlXPathFreeContext(xpath);
    xmlFreeDoc(doc);
}
示例#12
0
文件: spmxml.cpp 项目: smurav/gis36
bool CSpmXml::PopQuery()
{
	if (0 == m_lstSets.size())
		return false;

	if (m_pCurNodeSet)
		xmlXPathFreeNodeSet(m_pCurNodeSet);

	CNodeSet& nodeset = m_lstSets.back();
	m_pCurNodeSet = nodeset.set;
	m_nCurItem = nodeset.cur;
	m_lstSets.pop_back();
	return true;
}
示例#13
0
文件: spmxml.cpp 项目: smurav/gis36
xmlNodePtr CSpmXml::MoveFirst(const QString& strXPathQuery, xmlNodePtr pParent, int* pnCount)
{
	if (strXPathQuery.isEmpty())
		return 0;

	pParent = GetNode(pParent);
	if (0 == pParent)
		return 0;

	QString strQuery;
	if (strXPathQuery.left(2) != "//") // локальный запрос
	{
		strQuery = (char *)xmlGetNodePath(pParent);
		strQuery += strXPathQuery;
	}
	else
		strQuery = strXPathQuery;

	xmlXPathContextPtr pContext = xmlXPathNewContext(m_pXMLDoc);
	if (0 == pContext)
		return 0;

	xmlXPathObjectPtr pQuery = xmlXPathEvalExpression(BAD_CAST strQuery.toUtf8().data(), pContext);
	xmlXPathFreeContext(pContext);

	if (0 == pQuery)
		return 0;

	if (m_pCurNodeSet)
	{
		xmlXPathFreeNodeSet(m_pCurNodeSet);
		m_pCurNodeSet	= 0;
	}

	m_nCurItem = 0;

	m_pCurNodeSet = pQuery->nodesetval;
	if (0 == m_pCurNodeSet)
		return 0;

	if (pnCount)
		*pnCount = m_pCurNodeSet->nodeNr;

	if (0 == m_pCurNodeSet->nodeNr)
		return 0;

	m_pCurNode = m_pCurNodeSet->nodeTab[m_nCurItem];
	return m_pCurNode;
}
示例#14
0
/*
 * Load preferences.
 */
static void
gdisp_loadPreferences ( Kernel_T *kernel,
			xmlDoc   *document )
{

  xmlNodeSet   *preferenceTableNode = (xmlNodeSet*)NULL;
  xmlNode      *preferenceNode      = (xmlNode*)NULL;
  xmlChar      *propertyValue       = (xmlChar*)NULL;
  unsigned int  cptPreference       = 0;


  /*
   * Get back information.
   */
  preferenceTableNode =
    gdisp_xmlGetChildren(document,(xmlNode*)NULL, BAD_CAST "//Preferences/preference");

  if (preferenceTableNode != (xmlNodeSet*)NULL &&
      preferenceTableNode->nodeNr > 0) {

    for (cptPreference=0;
	 cptPreference<preferenceTableNode->nodeNr;
	 cptPreference++) {

      preferenceNode = preferenceTableNode->nodeTab[cptPreference];

      propertyValue = xmlGetProp(preferenceNode,
				 preferenceNode->properties->name);

      gdisp_setUpPreferenceFromString(kernel,
				      (gchar*)preferenceNode->properties->name,
				      (gchar*)propertyValue);

      xmlFree(propertyValue);

    }

  }


  /*
   * Free node set.
   */
  xmlXPathFreeNodeSet(preferenceTableNode);

}
示例#15
0
/**
 * xmlSecNodeSetGetChildren:
 * @doc: 		the pointer to an XML document.
 * @parent:	 	the pointer to parent XML node or NULL if we want to include all document nodes.
 * @withComments: 	the flag include  comments or not.
 * @invert: 		the "invert" flag.
 *
 * Creates a new nodes set that contains:
 *  - if @withComments is not 0 and @invert is 0:
 *    all nodes in the @parent subtree;
 *  - if @withComments is 0 and @invert is 0:
 *    all nodes in the @parent subtree except comment nodes;
 *  - if @withComments is not 0 and @invert not is 0:
 *    all nodes in the @doc except nodes in the @parent subtree;
 *  - if @withComments is 0 and @invert is 0:
 *    all nodes in the @doc except nodes in the @parent subtree 
 *    and comment nodes.
 *
 * Returns pointer to the newly created #xmlSecNodeSet structure
 * or NULL if an error occurs.
 */
EXPORT_C
xmlSecNodeSetPtr	
xmlSecNodeSetGetChildren(xmlDocPtr doc, const xmlNodePtr parent, int withComments, int invert) {
    xmlNodeSetPtr nodes;
    xmlSecNodeSetType type;
    xmlSecNodeSetPtr result = NULL;

    xmlSecAssert2(doc != NULL, NULL);
        
    nodes = xmlXPathNodeSetCreate(parent);
    if(nodes == NULL) {
	xmlSecError(XMLSEC_ERRORS_HERE,
		    NULL,
		    "xmlXPathNodeSetCreate",
		    XMLSEC_ERRORS_R_XML_FAILED,
		    XMLSEC_ERRORS_NO_MESSAGE);
	return(NULL);
    }	
    
    /* if parent is NULL then we add all the doc children */
    if(parent == NULL) {
	xmlNodePtr cur;
	for(cur = doc->children; cur != NULL; cur = cur->next) {
	    if(withComments || (cur->type != XML_COMMENT_NODE)) {
	        xmlXPathNodeSetAdd(nodes, cur);
	    }
	}
    }

    if(withComments && invert) {
	type = xmlSecNodeSetTreeInvert;
    } else if(withComments && !invert) {
	type = xmlSecNodeSetTree;
    } else if(!withComments && invert) {
	type = xmlSecNodeSetTreeWithoutCommentsInvert;
    } else { /* if(!withComments && !invert) */
	type = xmlSecNodeSetTreeWithoutComments;
    }

    result = xmlSecNodeSetCreate(doc, nodes, type);
    if ( !result )
        {
        xmlXPathFreeNodeSet( nodes );   
        }
    return result;
}
示例#16
0
void NavigationTable::LoadChildElements(NavigationElement *pElement, xmlNodePtr olNode)
{
    XPathWrangler xpath(olNode->doc, {{"epub", ePub3NamespaceURI}});
    xpath.NameDefaultNamespace("html");

    xmlNodeSetPtr liNodes = xpath.Nodes("./html:li", olNode);

    for ( size_t i = 0; i < liNodes->nodeNr; i++ )
    {
        NavigationElement* childElement = BuildNavigationPoint(liNodes->nodeTab[i]);
        if(childElement != nullptr)
        {
            pElement->AppendChild(childElement);
        }
    }

    xmlXPathFreeNodeSet(liNodes);
}
示例#17
0
文件: spmxml.cpp 项目: smurav/gis36
bool CSpmXml::DeleteNodes(const QString& strXPathQuery, xmlNodePtr pParent)
{
	if (strXPathQuery.isEmpty())
		return false;

	pParent = GetNode(pParent);
	if (0 == pParent)
		return false;

	QString strQuery;
	if (strXPathQuery.left(2) != "//") // локальный запрос
	{
		strQuery = (char *)xmlGetNodePath(pParent);
		strQuery += strXPathQuery;
	}
	else
		strQuery = strXPathQuery;

	xmlXPathContextPtr pContext = xmlXPathNewContext(m_pXMLDoc);
	if (0 == pContext)
		return false;

	xmlXPathObjectPtr pQuery = xmlXPathEvalExpression(BAD_CAST strQuery.toUtf8().data(), pContext);
	xmlXPathFreeContext(pContext);
	if (0 == pQuery)
		return false;

	xmlNodeSetPtr pNodeSet = pQuery->nodesetval;
	if ((0 == pNodeSet) || (0 == pNodeSet->nodeNr))
		return false;

	for (int i = 0; i < pNodeSet->nodeNr; i++)
	{
		xmlNodePtr pNode = pNodeSet->nodeTab[i];
		xmlUnlinkNode(pNode);
		SetModified();
	}

	xmlXPathFreeNodeSet(pNodeSet);
	return true;
}
示例#18
0
NavigationList PackageBase::NavTablesFromManifestItem(shared_ptr<PackageBase> owner, shared_ptr<ManifestItem> pItem)
{
    PackagePtr sharedPkg = std::dynamic_pointer_cast<Package>(owner);
    if ( !sharedPkg )
        return NavigationList();
    
    if ( pItem == nullptr )
        return NavigationList();
    
    xmlDocPtr doc = pItem->ReferencedDocument();
    if ( doc == nullptr )
        return NavigationList();
    
    // find each <nav> node
#if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS)
    XPathWrangler xpath(doc, {{"epub", ePub3NamespaceURI}}); // goddamn I love C++11 initializer list constructors
#else
    XPathWrangler::NamespaceList __m;
    __m["epub"] = ePub3NamespaceURI;
    XPathWrangler xpath(doc, __m);
#endif
    xpath.NameDefaultNamespace("html");
    
    xmlNodeSetPtr nodes = xpath.Nodes("//html:nav");
    
    NavigationList tables;
    for ( int i = 0; i < nodes->nodeNr; i++ )
    {
        xmlNodePtr navNode = nodes->nodeTab[i];
        auto navTablePtr = std::make_shared<class NavigationTable>(sharedPkg, pItem->Href());
        if ( navTablePtr->ParseXML(navNode) )
            tables.push_back(navTablePtr);
    }
    
    xmlXPathFreeNodeSet(nodes);
    
    // now look for any <dl> nodes with an epub:type of "glossary"
    nodes = xpath.Nodes("//html:dl[epub:type='glossary']");
    
    return tables;
}
示例#19
0
void Container::LoadEncryption()
{
    ContainerPtr sharedThis(shared_from_this());
    unique_ptr<ArchiveReader> pZipReader = _archive->ReaderAtPath(gEncryptionFilePath);
    if ( !pZipReader )
        return;
    
    ArchiveXmlReader reader(std::move(pZipReader));
    xmlDocPtr enc = reader.xmlReadDocument(gEncryptionFilePath, nullptr, XML_PARSE_RECOVER|XML_PARSE_NOENT|XML_PARSE_DTDATTR);
    if ( enc == nullptr )
        return;
#if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS)
    XPathWrangler xpath(enc, {{"enc", XMLENCNamespaceURI}, {"ocf", OCFNamespaceURI}});
#else
    XPathWrangler::NamespaceList __ns;
    __ns["ocf"] = OCFNamespaceURI;
    __ns["enc"] = XMLENCNamespaceURI;
    XPathWrangler xpath(enc, __ns);
#endif
    xmlNodeSetPtr nodes = xpath.Nodes("/ocf:encryption/enc:EncryptedData");
    if ( nodes == nullptr || nodes->nodeNr == 0 )
    {
        xmlChar* mem = nullptr;
        int size = 0;
        xmlDocDumpMemory(enc, &mem, &size);
        printf("%s\n", reinterpret_cast<char*>(mem));
        xmlFree(mem);
        return;     // should be a hard error?
    }
    
    for ( int i = 0; i < nodes->nodeNr; i++ )
    {
        auto encPtr = std::make_shared<EncryptionInfo>(sharedThis);
        if ( encPtr->ParseXML(nodes->nodeTab[i]) )
            _encryption.push_back(encPtr);
    }
    
    xmlXPathFreeNodeSet(nodes);
}
示例#20
0
文件: spmxml.cpp 项目: smurav/gis36
xmlNodePtr CSpmXml::MoveNext()
{
	if (0 == m_pXMLDoc)
		return 0;

	if (0 == m_pCurNodeSet)
		return 0;

	m_nCurItem++;

	if (m_nCurItem < m_pCurNodeSet->nodeNr)
	{
		m_pCurNode = m_pCurNodeSet->nodeTab[m_nCurItem];
		return m_pCurNode;
	}
	else
	{
		xmlXPathFreeNodeSet(m_pCurNodeSet);
		m_pCurNodeSet = 0;
		m_nCurItem = 0;
		return 0;
	}
}
示例#21
0
void Container::LoadEncryption()
{
    ArchiveReader *pZipReader = _archive->ReaderAtPath(gEncryptionFilePath);
    if ( pZipReader == nullptr )
        return;

    ArchiveXmlReader reader(pZipReader);
    xmlDocPtr enc = reader.xmlReadDocument(gEncryptionFilePath, nullptr, XML_PARSE_RECOVER|XML_PARSE_NOENT|XML_PARSE_DTDATTR);
    if ( enc == nullptr )
        return;

    XPathWrangler xpath(enc, {{"enc", XMLENCNamespaceURI}, {"ocf", OCFNamespaceURI}});
    xmlNodeSetPtr nodes = xpath.Nodes("/ocf:encryption/enc:EncryptedData");
    if ( nodes == nullptr || nodes->nodeNr == 0 )
        return;     // should be a hard error?

    for ( size_t i = 0; i < nodes->nodeNr; i++ )
    {
        _encryption.emplace_back(new EncryptionInfo(nodes->nodeTab[i]));
    }

    xmlXPathFreeNodeSet(nodes);
}
示例#22
0
void NavigationTable::LoadChildElements(shared_ptr<NavigationElement> pElement, xmlNodePtr olNode)
{
#if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS)
    XPathWrangler xpath(olNode->doc, {{"epub", ePub3NamespaceURI}});
#else
    XPathWrangler::NamespaceList __ns;
    __ns["ePub3"] = ePub3NamespaceURI;
    XPathWrangler xpath(olNode->doc, __ns);
#endif
    xpath.NameDefaultNamespace("html");

    xmlNodeSetPtr liNodes = xpath.Nodes("./html:li", olNode);

    for ( int i = 0; i < liNodes->nodeNr; i++ )
    {
        auto childElement = BuildNavigationPoint(liNodes->nodeTab[i]);
        if ( childElement )
        {
            pElement->AppendChild(childElement);
        }
    }

    xmlXPathFreeNodeSet(liNodes);
}
static void
xsltp_extension_string_join(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlChar *ret = NULL, *sep = NULL, *str = NULL;
    xmlNodeSetPtr nodeSet = NULL;
    int i, j;

    if (nargs  < 2) {
        xmlXPathSetArityError(ctxt);
        return;
    }

    if (xmlXPathStackIsNodeSet(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }

    sep = xmlXPathPopString(ctxt);

    for (i = 1; i < nargs; i++) {
        if (!xmlXPathStackIsNodeSet(ctxt)) {
            str = xmlXPathPopString(ctxt);

            if (i == 1) {
                ret = str;
            }
            else {
                str = xmlStrcat(str, sep);
                str = xmlStrcat(str, ret);
                xmlFree(ret);
                ret = str;
            }
        }
        else {
            nodeSet = xmlXPathPopNodeSet(ctxt);
            if (xmlXPathCheckError(ctxt)) {
                xmlXPathSetTypeError(ctxt);
                goto fail;
            }

            for (j = nodeSet->nodeNr - 1; j >= 0; j--) {
                str = xmlXPathCastNodeToString(nodeSet->nodeTab[j]);

                if (i == 1 && j == (nodeSet->nodeNr - 1)) {
                    ret = str;
                }
                else {
                    str = xmlStrcat(str, sep);
                    str = xmlStrcat(str, ret);
                    xmlFree(ret);
                    ret = str;
                }
            }

            xmlXPathFreeNodeSet(nodeSet);
        }
    }

    xmlXPathReturnString(ctxt, ret);

fail:
    if (sep != NULL)
        xmlFree(sep);
}
示例#24
0
/**
 *  'update' operation
 */
static void
edUpdate(xmlDocPtr doc, xmlNodeSetPtr nodes, const char *val,
    XmlNodeType type, xmlXPathContextPtr ctxt)
{
    int i;
    xmlXPathCompExprPtr xpath = NULL;

    if (type == XML_EXPR) {
        xpath = xmlXPathCompile((const xmlChar*) val);
        if (!xpath) return;
    }

    for (i = 0; i < nodes->nodeNr; i++)
    {
        /* update node */
        if (type == XML_EXPR) {
            xmlXPathObjectPtr res;

            ctxt->node = nodes->nodeTab[i];
            res = xmlXPathCompiledEval(xpath, ctxt);
            if (res->type == XPATH_NODESET || res->type == XPATH_XSLT_TREE) {
                int j;
                xmlNodePtr oldChild;
                xmlNodeSetPtr oldChildren = xmlXPathNodeSetCreate(NULL);
                /* NOTE: newChildren can be NULL for empty result set */
                xmlNodeSetPtr newChildren = res->nodesetval;

                /* NOTE: nodes can be both oldChildren and newChildren */

                /* unlink the old children */
                for (oldChild = nodes->nodeTab[i]->children; oldChild; oldChild = oldChild->next) {
                    xmlUnlinkNode(oldChild);
                    /* we can't free it now because an oldChild can also be
                       newChild! just put it in the list */
                    xmlXPathNodeSetAdd(oldChildren, oldChild);
                }

                /* add the new children */
                for (j = 0; newChildren && j < newChildren->nodeNr; j++) {
                    xmlNodePtr node = newChildren->nodeTab[j];
                    xmlAddChild(nodes->nodeTab[i],
                        /* if node is linked to this doc we need to copy */
                        (node->doc == doc)? xmlDocCopyNode(node, doc, 1) : node);
                    newChildren->nodeTab[j] = NULL;
                }
                newChildren->nodeNr = 0;

                /* NOTE: if any oldChildren were newChildren, they've been
                   copied so we can free them all now */
                for (j = 0; j < oldChildren->nodeNr; j++) {
                    xmlFreeNode(oldChildren->nodeTab[j]);
                    oldChildren->nodeTab[j] = NULL;
                }
                oldChildren->nodeNr = 0;
                xmlXPathFreeNodeSet(oldChildren);
            } else {
                res = xmlXPathConvertString(res);
                update_string(doc, nodes->nodeTab[i], res->stringval);
            }
            xmlXPathFreeObject(res);
        } else {
            update_string(doc, nodes->nodeTab[i], (const xmlChar*) val);
        }
    }

    xmlXPathFreeCompExpr(xpath);
}
示例#25
0
bool Package::Unpack()
{
    PackagePtr sharedMe = shared_from_this();
    
    // very basic sanity check
    xmlNodePtr root = xmlDocGetRootElement(_opf);
    string rootName(reinterpret_cast<const char*>(root->name));
    rootName.tolower();
    
    if ( rootName != "package" )
    {
        HandleError(EPUBError::OPFInvalidPackageDocument);
        return false;       // not an OPF file, innit?
    }
    if ( _getProp(root, "version").empty() )
    {
        HandleError(EPUBError::OPFPackageHasNoVersion);
    }
    
    InstallPrefixesFromAttributeValue(_getProp(root, "prefix", ePub3NamespaceURI));
    
    // go through children to determine the CFI index of the <spine> tag
    static const xmlChar* kSpineName = BAD_CAST "spine";
    static const xmlChar* kManifestName = BAD_CAST "manifest";
    static const xmlChar* kMetadataName = BAD_CAST "metadata";
    _spineCFIIndex = 0;
    uint32_t idx = 0;
    xmlNodePtr child = xmlFirstElementChild(root);
    while ( child != nullptr )
    {
        idx += 2;
        if ( xmlStrEqual(child->name, kSpineName) )
        {
            _spineCFIIndex = idx;
            if ( _spineCFIIndex != 6 )
                HandleError(EPUBError::OPFSpineOutOfOrder);
        }
        else if ( xmlStrEqual(child->name, kManifestName) && idx != 4 )
        {
            HandleError(EPUBError::OPFManifestOutOfOrder);
        }
        else if ( xmlStrEqual(child->name, kMetadataName) && idx != 2 )
        {
            HandleError(EPUBError::OPFMetadataOutOfOrder);
        }
        
        child = xmlNextElementSibling(child);
    }
    
    if ( _spineCFIIndex == 0 )
    {
        HandleError(EPUBError::OPFNoSpine);
        return false;       // spineless!
    }
    
#if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS)
    XPathWrangler xpath(_opf, {{"opf", OPFNamespace}, {"dc", DCNamespace}});
#else
    XPathWrangler::NamespaceList __m;
    __m["opf"] = OPFNamespace;
    __m["dc"] = DCNamespace;
    XPathWrangler xpath(_opf, __m);
#endif
    
    // simple things: manifest and spine items
    xmlNodeSetPtr manifestNodes = nullptr;
    xmlNodeSetPtr spineNodes = nullptr;
    
    try
    {
        manifestNodes = xpath.Nodes("/opf:package/opf:manifest/opf:item");
        spineNodes = xpath.Nodes("/opf:package/opf:spine/opf:itemref");
        
        if ( manifestNodes == nullptr )
        {
            HandleError(EPUBError::OPFNoManifestItems);
        }
        
        if ( spineNodes == nullptr )
        {
            HandleError(EPUBError::OPFNoSpineItems);
        }
        
        for ( int i = 0; i < manifestNodes->nodeNr; i++ )
        {
            auto p = std::make_shared<ManifestItem>(sharedMe);
            if ( p->ParseXML(p, manifestNodes->nodeTab[i]) )
            {
#if EPUB_HAVE(CXX_MAP_EMPLACE)
                _manifest.emplace(p->Identifier(), p);
#else
                _manifest[p->Identifier()] = p;
#endif
                StoreXMLIdentifiable(p);
            }
            else
            {
                // TODO: Need an error here
            }
        }
        
        // check fallback chains
        typedef std::map<string, bool> IdentSet;
        IdentSet idents;
        for ( auto &pair : _manifest )
        {
            ManifestItemPtr item = pair.second;
            if ( item->FallbackID().empty() )
                continue;
            
            idents[item->XMLIdentifier()] = true;
            while ( !item->FallbackID().empty() )
            {
                if ( idents[item->FallbackID()] )
                {
                    HandleError(EPUBError::OPFFallbackChainCircularReference);
                    break;
                }
                
                item = item->Fallback();
            }
            
            idents.clear();
        }
        
        SpineItemPtr cur;
        for ( int i = 0; i < spineNodes->nodeNr; i++ )
        {
            auto next = std::make_shared<SpineItem>(sharedMe);
            if ( next->ParseXML(next, spineNodes->nodeTab[i]) == false )
            {
                // TODO: need an error code here
                continue;
            }
            
            // validation of idref
            auto manifestFound = _manifest.find(next->Idref());
            if ( manifestFound == _manifest.end() )
            {
                HandleError(EPUBError::OPFInvalidSpineIdref, _Str(next->Idref(), " does not correspond to a manifest item"));
                continue;
            }
            
            // validation of spine resource type w/fallbacks
            ManifestItemPtr manifestItem = next->ManifestItem();
            bool isContentDoc = false;
            do
            {
                if ( manifestItem->MediaType() == "application/xhtml+xml" ||
                     manifestItem->MediaType() == "image/svg" )
                {
                    isContentDoc = true;
                    break;
                }
                
            } while ( (manifestItem = manifestItem->Fallback()) );
            
            if ( !isContentDoc )
                HandleError(EPUBError::OPFFallbackChainHasNoContentDocument);
            
            StoreXMLIdentifiable(next);
            
            if ( cur != nullptr )
            {
                cur->SetNextItem(next);
            }
            else
            {
                _spine = next;
            }
            
            cur = next;
        }
    }
    catch (const std::system_error& exc)
    {
        if ( manifestNodes != nullptr )
            xmlXPathFreeNodeSet(manifestNodes);
        if ( spineNodes != nullptr )
            xmlXPathFreeNodeSet(spineNodes);
        if ( exc.code().category() == epub_spec_category() )
            throw;
        return false;
    }
    catch (...)
    {
        if ( manifestNodes != nullptr )
            xmlXPathFreeNodeSet(manifestNodes);
        if ( spineNodes != nullptr )
            xmlXPathFreeNodeSet(spineNodes);
        return false;
    }
    
    xmlXPathFreeNodeSet(manifestNodes);
    xmlXPathFreeNodeSet(spineNodes);
    
    // now the metadata, which is slightly more involved due to extensions
    xmlNodeSetPtr metadataNodes = nullptr;
    xmlNodeSetPtr refineNodes = xmlXPathNodeSetCreate(nullptr);
    
    try
    {
        shared_ptr<PropertyHolder> holderPtr = std::dynamic_pointer_cast<PropertyHolder>(sharedMe);
        metadataNodes = xpath.Nodes("/opf:package/opf:metadata/*");
        if ( metadataNodes == nullptr )
            HandleError(EPUBError::OPFNoMetadata);
        
        bool foundIdentifier = false, foundTitle = false, foundLanguage = false, foundModDate = false;
        string uniqueIDRef = _getProp(root, "unique-identifier");
        if ( uniqueIDRef.empty() )
            HandleError(EPUBError::OPFPackageUniqueIDInvalid);
        
        for ( int i = 0; i < metadataNodes->nodeNr; i++ )
        {
            xmlNodePtr node = metadataNodes->nodeTab[i];
            PropertyPtr p;
            
            if ( node->ns != nullptr && xmlStrcmp(node->ns->href, BAD_CAST DCNamespace) == 0 )
            {
                // definitely a main node
                p = std::make_shared<Property>(holderPtr);
            }
            else if ( _getProp(node, "name").size() > 0 )
            {
                // it's an ePub2 item-- ignore it
                continue;
            }
            else if ( _getProp(node, "refines").empty() )
            {
                // not refining anything, so it's a main node
                p = std::make_shared<Property>(holderPtr);
            }
            else
            {
                // by elimination it's refining something-- we'll process it later when we know we've got all the main nodes in there
                xmlXPathNodeSetAdd(refineNodes, node);
            }
            
            if ( p && p->ParseMetaElement(node) )
            {
                switch ( p->Type() )
                {
                    case DCType::Identifier:
                    {
                        foundIdentifier = true;
                        if ( !uniqueIDRef.empty() && uniqueIDRef != p->XMLIdentifier() )
                            HandleError(EPUBError::OPFPackageUniqueIDInvalid);
                        break;
                    }
                    case DCType::Title:
                    {
                        foundTitle = true;
                        break;
                    }
                    case DCType::Language:
                    {
                        foundLanguage = true;
                        break;
                    }
                    case DCType::Custom:
                    {
                        if ( p->PropertyIdentifier() == MakePropertyIRI("modified", "dcterms") )
                            foundModDate = true;
                        break;
                    }
                        
                    default:
                        break;
                }
                
                AddProperty(p);
                StoreXMLIdentifiable(p);
            }
        }
        
        if ( !foundIdentifier )
            HandleError(EPUBError::OPFMissingIdentifierMetadata);
        if ( !foundTitle )
            HandleError(EPUBError::OPFMissingTitleMetadata);
        if ( !foundLanguage )
            HandleError(EPUBError::OPFMissingLanguageMetadata);
        if ( !foundModDate )
            HandleError(EPUBError::OPFMissingModificationDateMetadata);
        
        for ( int i = 0; i < refineNodes->nodeNr; i++ )
        {
            xmlNodePtr node = refineNodes->nodeTab[i];
            string ident = _getProp(node, "refines");
            if ( ident.empty() )
            {
                HandleError(EPUBError::OPFInvalidRefinementAttribute, "Empty IRI for 'refines' attribute");
                continue;
            }
            
            if ( ident[0] == '#' )
            {
                ident = ident.substr(1);
            }
            else
            {
                // validation only right now
                IRI iri(ident);
                if ( iri.IsEmpty() )
                {
                    HandleError(EPUBError::OPFInvalidRefinementAttribute, _Str("#", ident, " is not a valid IRI"));
                }
                else if ( iri.IsRelative() == false )
                {
                    HandleError(EPUBError::OPFInvalidRefinementAttribute, _Str(iri.IRIString(), " is not a relative IRI"));
                }
                continue;
            }
            
            auto found = _xmlIDLookup.find(ident);
            if ( found == _xmlIDLookup.end() )
            {
                HandleError(EPUBError::OPFInvalidRefinementTarget, _Str("#", ident, " does not reference an item in this document"));
                continue;
            }
            
            PropertyPtr prop = std::dynamic_pointer_cast<Property>(found->second);
            if ( prop )
            {
                // it's a property, so this is an extension
                PropertyExtensionPtr extPtr = std::make_shared<PropertyExtension>(prop);
                if ( extPtr->ParseMetaElement(node) )
                    prop->AddExtension(extPtr);
            }
            else
            {
                // not a property, so treat this as a plain property
                shared_ptr<PropertyHolder> ptr = std::dynamic_pointer_cast<PropertyHolder>(found->second);
                if ( ptr )
                {
                    prop = std::make_shared<Property>(ptr);
                    if ( prop->ParseMetaElement(node) )
                        ptr->AddProperty(prop);
                }
            }
        }
        
        // now look at the <spine> element for properties
        xmlNodePtr spineNode = xmlFirstElementChild(root);
        for ( uint32_t i = 2; i < _spineCFIIndex; i += 2 )
            spineNode = xmlNextElementSibling(spineNode);
        
        string value = _getProp(spineNode, "page-progression-direction");
        if ( !value.empty() )
        {
            PropertyPtr prop = std::make_shared<Property>(holderPtr);
            prop->SetPropertyIdentifier(MakePropertyIRI("page-progression-direction"));
            prop->SetValue(value);
            AddProperty(prop);
        }
    }
    catch (std::system_error& exc)
    {
        if ( metadataNodes != nullptr )
            xmlXPathFreeNodeSet(metadataNodes);
        if ( refineNodes != nullptr )
            xmlXPathFreeNodeSet(refineNodes);
        if ( exc.code().category() == epub_spec_category() )
            throw;
        return false;
    }
    catch (...)
    {
        if ( metadataNodes != nullptr )
            xmlXPathFreeNodeSet(metadataNodes);
        if ( refineNodes != nullptr )
            xmlXPathFreeNodeSet(refineNodes);
        return false;
    }
    
    xmlXPathFreeNodeSet(metadataNodes);
    xmlXPathFreeNodeSet(refineNodes);
    
    // now any content type bindings
    xmlNodeSetPtr bindingNodes = nullptr;
    
    try
    {
        bindingNodes = xpath.Nodes("/opf:package/opf:bindings/*");
        if ( bindingNodes != nullptr )
        {
            for ( int i = 0; i < bindingNodes->nodeNr; i++ )
            {
                xmlNodePtr node = bindingNodes->nodeTab[i];
                if ( xmlStrcasecmp(node->name, MediaTypeElementName) != 0 )
                    continue;
                
                ////////////////////////////////////////////////////////////
                // ePub Publications 3.0 §3.4.16: The `mediaType` Element
                
                // The media-type attribute is required.
                string mediaType = _getProp(node, "media-type");
                if ( mediaType.empty() )
                {
                    HandleError(EPUBError::OPFBindingHandlerNoMediaType);
                    throw false;
                }
                
                // Each child mediaType of a bindings element must define a unique
                // content type in its media-type attribute, and the media type
                // specified must not be a Core Media Type.
                if ( _contentHandlers[mediaType].empty() == false )
                {
                    // user shouldn't have added manual things yet, but for safety we'll look anyway
                    for ( auto ptr : _contentHandlers[mediaType] )
                    {
                        if ( typeid(*ptr) == typeid(MediaHandler) )
                        {
                            HandleError(EPUBError::OPFMultipleBindingsForMediaType);
                        }
                    }
                }
                if ( CoreMediaTypes.find(mediaType) != CoreMediaTypes.end() )
                {
                    HandleError(EPUBError::OPFCoreMediaTypeBindingEncountered);
                }
                
                // The handler attribute is required
                string handlerID = _getProp(node, "handler");
                if ( handlerID.empty() )
                {
                    HandleError(EPUBError::OPFBindingHandlerNotFound);
                }
                
                // The required handler attribute must reference the ID [XML] of an
                // item in the manifest of the default implementation for this media
                // type. The referenced item must be an XHTML Content Document.
                ManifestItemPtr handlerItem = ManifestItemWithID(handlerID);
                if ( !handlerItem )
                {
                    HandleError(EPUBError::OPFBindingHandlerNotFound);
                }
                if ( handlerItem->MediaType() != "application/xhtml+xml" )
                {
                    
                    HandleError(EPUBError::OPFBindingHandlerInvalidType, _Str("Media handlers must be XHTML content documents, but referenced item has type '", handlerItem->MediaType(), "'."));
                }
                
                // All XHTML Content Documents designated as handlers must have the
                // `scripted` property set in their manifest item's `properties`
                // attribute.
                if ( handlerItem->HasProperty(ItemProperties::HasScriptedContent) == false )
                {
                    HandleError(EPUBError::OPFBindingHandlerNotScripted);
                }
                
                // all good-- install it now
                _contentHandlers[mediaType].push_back(std::make_shared<MediaHandler>(sharedMe, mediaType, handlerItem->AbsolutePath()));
            }
        }
    }
    catch (std::exception& exc)
    {
        std::cerr << "Exception processing OPF file: " << exc.what() << std::endl;
        if ( bindingNodes != nullptr )
            xmlXPathFreeNodeSet(bindingNodes);
        throw;
    }
    catch (...)
    {
        if ( bindingNodes != nullptr )
            xmlXPathFreeNodeSet(bindingNodes);
        return false;
    }
    
    xmlXPathFreeNodeSet(bindingNodes);
    
    // now the navigation tables
    for ( auto item : _manifest )
    {
        if ( !item.second->HasProperty(ItemProperties::Navigation) )
            continue;
        
        NavigationList tables = NavTablesFromManifestItem(sharedMe, item.second);
        for ( auto table : tables )
        {
            // have to dynamic_cast these guys to get the right pointer type
            shared_ptr<class NavigationTable> navTable = std::dynamic_pointer_cast<class NavigationTable>(table);
#if EPUB_HAVE(CXX_MAP_EMPLACE)
            _navigation.emplace(navTable->Type(), navTable);
#else
            _navigation[navTable->Type()] = navTable;
#endif
        }
    }
    
    // lastly, let's set the media support information
    InitMediaSupport();
    
    return true;
}
示例#26
0
/**
 * exsltStrReplaceFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * Takes a string, and two node sets and returns the string with all strings in
 * the first node set replaced by all strings in the second node set.
 */
static void
exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    int i, i_empty, n, slen0, rlen0, *slen, *rlen;
    void *mem = NULL;
    const xmlChar *src, *start;
    xmlChar *string, *search_str = NULL, *replace_str = NULL;
    xmlChar **search, **replace;
    xmlNodeSetPtr search_set = NULL, replace_set = NULL;
    xmlBufferPtr buf;

    if (nargs  != 3) {
        xmlXPathSetArityError(ctxt);
        return;
    }

    /* get replace argument */

    if (!xmlXPathStackIsNodeSet(ctxt))
        replace_str = xmlXPathPopString(ctxt);
    else
        replace_set = xmlXPathPopNodeSet(ctxt);

    if (xmlXPathCheckError(ctxt))
        goto fail_replace;

    /* get search argument */

    if (!xmlXPathStackIsNodeSet(ctxt)) {
        search_str = xmlXPathPopString(ctxt);
        n = 1;
    }
    else {
        search_set = xmlXPathPopNodeSet(ctxt);
        n = search_set != NULL ? search_set->nodeNr : 0;
    }

    if (xmlXPathCheckError(ctxt))
        goto fail_search;

    /* get string argument */

    string = xmlXPathPopString(ctxt);
    if (xmlXPathCheckError(ctxt))
        goto fail_string;

    /* check for empty search node list */

    if (n <= 0) {
        exsltStrReturnString(ctxt, string, xmlStrlen(string));
        goto done_empty_search;
    }

    /* allocate memory for string pointer and length arrays */

    if (n == 1) {
        search = &search_str;
        replace = &replace_str;
        slen = &slen0;
        rlen = &rlen0;
    }
    else {
        mem = xmlMalloc(2 * n * (sizeof(const xmlChar *) + sizeof(int)));
        if (mem == NULL) {
            xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
            goto fail_malloc;
        }
        search = (xmlChar **) mem;
        replace = search + n;
        slen = (int *) (replace + n);
        rlen = slen + n;
    }

    /* process arguments */

    i_empty = -1;

    for (i=0; i<n; ++i) {
        if (search_set != NULL) {
            search[i] = xmlXPathCastNodeToString(search_set->nodeTab[i]);
            if (search[i] == NULL) {
                n = i;
                goto fail_process_args;
            }
        }

        slen[i] = xmlStrlen(search[i]);
        if (i_empty < 0 && slen[i] == 0)
            i_empty = i;

        if (replace_set != NULL) {
            if (i < replace_set->nodeNr) {
                replace[i] = xmlXPathCastNodeToString(replace_set->nodeTab[i]);
                if (replace[i] == NULL) {
                    n = i + 1;
                    goto fail_process_args;
                }
            }
            else
                replace[i] = NULL;
        }
        else {
            if (i == 0)
                replace[i] = replace_str;
            else
                replace[i] = NULL;
        }

        if (replace[i] == NULL)
            rlen[i] = 0;
        else
            rlen[i] = xmlStrlen(replace[i]);
    }

    if (i_empty >= 0 && rlen[i_empty] == 0)
        i_empty = -1;

    /* replace operation */

    buf = xmlBufferCreate();
    if (buf == NULL) {
        xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
        goto fail_buffer;
    }
    src = string;
    start = string;

    while (*src != 0) {
        int max_len = 0, i_match = 0;

        for (i=0; i<n; ++i) {
            if (*src == search[i][0] &&
                slen[i] > max_len &&
                xmlStrncmp(src, search[i], slen[i]) == 0)
            {
                i_match = i;
                max_len = slen[i];
            }
        }

        if (max_len == 0) {
            if (i_empty >= 0 && start < src) {
                if (xmlBufferAdd(buf, start, src - start) ||
                    xmlBufferAdd(buf, replace[i_empty], rlen[i_empty]))
                {
                    xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
                    goto fail_buffer_add;
                }
                start = src;
            }

            src += xmlUTF8Size(src);
        }
        else {
            if ((start < src &&
                 xmlBufferAdd(buf, start, src - start)) ||
                (rlen[i_match] &&
                 xmlBufferAdd(buf, replace[i_match], rlen[i_match])))
            {
                xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
                goto fail_buffer_add;
            }

            src += slen[i_match];
            start = src;
        }
    }

    if (start < src && xmlBufferAdd(buf, start, src - start)) {
        xmlXPathSetError(ctxt, XPATH_MEMORY_ERROR);
        goto fail_buffer_add;
    }

    /* create result node set */

    exsltStrReturnString(ctxt, xmlBufferContent(buf), xmlBufferLength(buf));

    /* clean up */

fail_buffer_add:
    xmlBufferFree(buf);

fail_buffer:
fail_process_args:
    if (search_set != NULL) {
        for (i=0; i<n; ++i)
            xmlFree(search[i]);
    }
    if (replace_set != NULL) {
        for (i=0; i<n; ++i) {
            if (replace[i] != NULL)
                xmlFree(replace[i]);
        }
    }

    if (mem != NULL)
        xmlFree(mem);

fail_malloc:
done_empty_search:
    xmlFree(string);

fail_string:
    if (search_set != NULL)
        xmlXPathFreeNodeSet(search_set);
    else
        xmlFree(search_str);

fail_search:
    if (replace_set != NULL)
        xmlXPathFreeNodeSet(replace_set);
    else
        xmlFree(replace_str);

fail_replace:
    return;
}
示例#27
0
bool MainWindow::OpenOSM(const QString &file_name) {
  scene_.clear();
  FreeXMLDoc();

  xmlParserCtxtPtr xml_parser_ctx_ptr = xmlNewParserCtxt();
  if (0 == xml_parser_ctx_ptr)
    return false;

  // XML документ libxml2
  xml_doc_ptr_ = xmlCtxtReadFile(xml_parser_ctx_ptr,
                                 file_name.toLocal8Bit().data(),
                                 0,
                                 XML_PARSE_NOBLANKS);
  xmlFreeParserCtxt(xml_parser_ctx_ptr);
  xml_parser_ctx_ptr = 0;
  if (0 == xml_doc_ptr_)
    return false;

  xmlXPathContextPtr xpath_context_ptr = xmlXPathNewContext(xml_doc_ptr_);
  if (0 == xpath_context_ptr)
    return false;

  // Определеяем границы листа
  xmlXPathObjectPtr xpath_bounds_query = xmlXPathEvalExpression(
                                           BAD_CAST "//bounds",
                                           xpath_context_ptr);
  if ((0 == xpath_bounds_query) || (1 != xpath_bounds_query->nodesetval->nodeNr))
    return false;

  xmlNodePtr bounds = xpath_bounds_query->nodesetval->nodeTab[0];
  float minlat = QString::fromUtf8((char *)xmlGetProp(bounds, BAD_CAST "minlat")).toFloat();
  float minlon = QString::fromUtf8((char *)xmlGetProp(bounds, BAD_CAST "minlon")).toFloat();
  float maxlat = QString::fromUtf8((char *)xmlGetProp(bounds, BAD_CAST "maxlat")).toFloat();
  float maxlon = QString::fromUtf8((char *)xmlGetProp(bounds, BAD_CAST "maxlon")).toFloat();

  // Настраиваем область видимости
  ui->graphicsView->resetTransform();
  ui->graphicsView->centerOn((maxlon - minlon) * 0.5, (maxlat - minlat) * 0.5);
  ui->graphicsView->setResizeAnchor(QGraphicsView::AnchorViewCenter);

  qreal sx = 8000;
  qreal sy = 10000;

  ui->graphicsView->scale(sx, -sy);

  // Перебираем слои
  int layers_count = ui->treeWidget->topLevelItemCount();
  for (int layer_index = 0; layer_index < layers_count; layer_index++){
    QTreeWidgetItem *layer_item_ptr = ui->treeWidget->topLevelItem(layer_index);
    QString ways_count("0");
    layer_item_ptr->setText(LAYERS_OBJECTS_COUNT_COLUMN, ways_count);

    QString way_query = layer_item_ptr->data(LAYERS_XPATH_COLUMN, 0).toString();

    xmlXPathObjectPtr xpath_way_query = xmlXPathEvalExpression(
      BAD_CAST way_query.toUtf8().data(), xpath_context_ptr);

    if (0 == xpath_way_query)
      continue;

    xmlNodeSetPtr way_set = xpath_way_query->nodesetval;
    if ((0 == way_set) || (0 == way_set->nodeNr))
      continue;

    QPen pen(Qt::darkGray);
    QBrush brush(Qt::lightGray);
    QList<QGraphicsItem*> layer;

    ways_count.setNum(way_set->nodeNr);
    layer_item_ptr->setText(LAYERS_OBJECTS_COUNT_COLUMN, ways_count);

    for (int i = 0; i < way_set->nodeNr; i++){
      xmlNodePtr way = way_set->nodeTab[i];
      if (0 == way)
        continue;

      // Создаем массив точек
      QPolygonF polygon;

      QString way_id = QString::fromUtf8((char *)xmlGetProp(way, BAD_CAST "id"));
      QString nd_query = QString("//way[@id='%1']/nd").arg(way_id);

      // Перебираем ссылки на точки
      xmlXPathObjectPtr xpath_nd_query = xmlXPathEvalExpression(
                                           BAD_CAST nd_query.toUtf8().data(),
                                           xpath_context_ptr);
      if ((0 == xpath_nd_query) || (0 == xpath_nd_query->nodesetval))
        continue;

      for (int nd_index = 0;
           nd_index < xpath_nd_query->nodesetval->nodeNr;
           nd_index++){
        QString ref = QString::fromUtf8((char *)xmlGetProp(xpath_nd_query->nodesetval->nodeTab[nd_index], BAD_CAST "ref"));

        // Ищем точку
        QString node_query = QString("//node[@id='%1']").arg(ref);
        xmlXPathObjectPtr xpath_node_query = xmlXPathEvalExpression(
                                             BAD_CAST node_query.toUtf8().data(),
                                             xpath_context_ptr);
        if ((0 == xpath_node_query) || (1 != xpath_node_query->nodesetval->nodeNr))
          continue;

        xmlNodePtr node = xpath_node_query->nodesetval->nodeTab[0];
        QString latitude = QString::fromUtf8((char *)xmlGetProp(node, BAD_CAST "lat"));
        QString longitude = QString::fromUtf8((char *)xmlGetProp(node, BAD_CAST "lon"));
        polygon.append(QPointF(longitude.toFloat(), latitude.toFloat()));

        xmlXPathFreeNodeSet(xpath_node_query->nodesetval);
        xmlFree(xpath_node_query);
      }

      // Создаем графический объект
      QGraphicsPolygonItem *polygon_item = new QGraphicsPolygonItem(polygon);
      polygon_item->setPen(pen);
      polygon_item->setBrush(brush);
      layer.append(polygon_item);

      xmlXPathFreeNodeSet(xpath_nd_query->nodesetval);
      xmlFree(xpath_nd_query);
    }

    QGraphicsItemGroup* layer_group = scene_.createItemGroup(layer);

    xmlXPathFreeNodeSet(way_set);
    xmlFree(xpath_way_query);
  }

  xmlXPathFreeContext(xpath_context_ptr);
  xpath_context_ptr = 0;

  return true;
}
示例#28
0
/** This extension function is designed to be used in a sanity test with an
 * XPath expression like this:
 * "//entry[ fd:unbalanced-braces(.//orth | .//tr | .//note | .//def | .//q) ]"
 * Before its use, a namespace prefix like "fd" has to be bound to
 * FREEDICT_EDITOR_NAMESPACE.
 */
static void freedict_xpath_extension_unbalanced_braces(
    xmlXPathParserContextPtr ctxt, const int nargs)
{

  if(nargs != 1)
  {
    xmlXPathSetArityError(ctxt);
    return;
  }

  xmlNodeSetPtr ns = xmlXPathPopNodeSet(ctxt);
  if(xmlXPathCheckError(ctxt) || !ns)
  {
    xmlXPathFreeNodeSet(ns);
    return;
  }

  // function that does the actual parsing
  // returns TRUE if a brace of the string in c does not have
  // a corresponding brace
  gboolean contains_unbalanced_braces(xmlChar *c)
  {
    if(!c) return FALSE;
    char stack[100];
    int stackend = sizeof(stack);

    // returns FALSE on stack full
    gboolean cub_push(const char b)
    {
      if(!stackend)
      {
        g_printerr(G_STRLOC ": Too many open braces");
        return FALSE;
      }
      stack[--stackend] = b;
      return TRUE;
    }

    gchar cub_pop()
    {
      // stack is empty
      if(stackend>=sizeof(stack)) return 'E';

      return stack[stackend++];
    }

    do
    {
      switch(*c)
      {
        case '(': if(!cub_push('(')) return TRUE; break;
        case '[': if(!cub_push('[')) return TRUE; break;
        case '{': if(!cub_push('{')) return TRUE; break;

        case ')': if(cub_pop()!='(') return TRUE;break;
        case ']': if(cub_pop()!='[') return TRUE;break;
        case '}': if(cub_pop()!='{') return TRUE;break;

        // all other characters are skipped
      }
      c++;
    }
    while(*c);

    // braces left open?
    if(cub_pop()!='E') return TRUE;

    // this string is well formed in regard of braces
    return FALSE;
  }

  int result = FALSE;
  int i;
  for(i=0; i < xmlXPathNodeSetGetLength(ns); i++)
  {
    xmlNodePtr n = xmlXPathNodeSetItem(ns, i);
    xmlChar* c = xmlNodeGetContent(n);
    if(!c) continue;
    result = contains_unbalanced_braces(c);
    xmlFree(c);
    if(result) break;
  }

  if(ns) xmlXPathFreeNodeSet(ns);
  xmlXPathReturnBoolean(ctxt, result);
}
示例#29
0
/**
 * exsltStrReplaceFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * Takes a string, and two node sets and returns the string with all strings in
 * the first node set replaced by all strings in the second node set.
 */
static void
exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlChar *str = NULL, *searchStr = NULL, *replaceStr = NULL;
    xmlNodeSetPtr replaceSet = NULL, searchSet = NULL;
    xmlChar *ret = NULL, *retSwap = NULL;
    int i;

    if (nargs  != 3) {
        xmlXPathSetArityError(ctxt);
        return;
    }

    /* pull out replace argument */
    if (!xmlXPathStackIsNodeSet(ctxt)) {
        replaceStr = xmlXPathPopString(ctxt);
    }
    else {
        replaceSet = xmlXPathPopNodeSet(ctxt);
        if (xmlXPathCheckError(ctxt)) {
            xmlXPathSetTypeError(ctxt);
            goto fail;
        }
    }

    /* behavior driven by search argument from here on */
    if (!xmlXPathStackIsNodeSet(ctxt)) {
        searchStr = xmlXPathPopString(ctxt);
        str = xmlXPathPopString(ctxt);

        if (replaceStr == NULL) {
            xmlXPathSetTypeError(ctxt);
            goto fail;
        }

        ret = exsltStrReplaceInternal(str, searchStr, replaceStr);
    }
    else {
        searchSet = xmlXPathPopNodeSet(ctxt);
        if (searchSet == NULL || xmlXPathCheckError(ctxt)) {
            xmlXPathSetTypeError(ctxt);
            goto fail;
        }

        str = xmlXPathPopString(ctxt);
        ret = xmlStrdup(str);

        for (i = 0; i < searchSet->nodeNr; i++) {
            searchStr = xmlXPathCastNodeToString(searchSet->nodeTab[i]);

            if (replaceSet != NULL) {
                replaceStr = NULL;
                if (i < replaceSet->nodeNr) {
                    replaceStr = xmlXPathCastNodeToString(replaceSet->nodeTab[i]);
                }

                retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr);

                if (replaceStr != NULL) {
                    xmlFree(replaceStr);
                    replaceStr = NULL;
                }
            }
            else {
                retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr);
            }

            xmlFree(ret);
            if (searchStr != NULL) {
                xmlFree(searchStr);
                searchStr = NULL;
            }

            ret = retSwap;
        }

        if (replaceSet != NULL)
            xmlXPathFreeNodeSet(replaceSet);

        if (searchSet != NULL)
            xmlXPathFreeNodeSet(searchSet);
    }

    xmlXPathReturnString(ctxt, ret);

fail:
    if (replaceStr != NULL)
        xmlFree(replaceStr);

    if (searchStr != NULL)
        xmlFree(searchStr);

    if (str != NULL)
        xmlFree(str);
}
示例#30
0
static void
exsltDynMapFunction(xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlChar *str = NULL;
    xmlNodeSetPtr nodeset = NULL;
    xsltTransformContextPtr tctxt;
    xmlXPathCompExprPtr comp = NULL;
    xmlXPathObjectPtr ret = NULL;
    xmlDocPtr oldDoc, container = NULL;
    xmlNodePtr oldNode;
    int oldContextSize;
    int oldProximityPosition;
    int i, j;


    if (nargs != 2) {
        xmlXPathSetArityError(ctxt);
        return;
    }
    str = xmlXPathPopString(ctxt);
    if (xmlXPathCheckError(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }

    nodeset = xmlXPathPopNodeSet(ctxt);
    if (xmlXPathCheckError(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }
    if (str == NULL || !xmlStrlen(str) || !(comp = xmlXPathCompile(str))) {
        if (nodeset != NULL)
            xmlXPathFreeNodeSet(nodeset);
        if (str != NULL)
            xmlFree(str);
        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
        return;
    }

    ret = xmlXPathNewNodeSet(NULL);
    if (ret == NULL) {
        xsltGenericError(xsltGenericErrorContext,
                         "exsltDynMapFunction: ret == NULL\n");
        goto cleanup;
    }

    oldDoc = ctxt->context->doc;
    oldNode = ctxt->context->node;
    oldContextSize = ctxt->context->contextSize;
    oldProximityPosition = ctxt->context->proximityPosition;

    tctxt = xsltXPathGetTransformContext(ctxt);
    if (tctxt == NULL) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
	      "dyn:map : internal error tctxt == NULL\n");
	goto cleanup;
    }
    container = xsltCreateRVT(tctxt);
    if (container == NULL) {
	xsltTransformError(tctxt, NULL, NULL,
	      "dyn:map : internal error container == NULL\n");
	goto cleanup;
    }
    xsltRegisterLocalRVT(tctxt, container);
    if (nodeset && nodeset->nodeNr > 0) {
        xmlXPathNodeSetSort(nodeset);
        ctxt->context->contextSize = nodeset->nodeNr;
        ctxt->context->proximityPosition = 0;
        for (i = 0; i < nodeset->nodeNr; i++) {
            xmlXPathObjectPtr subResult = NULL;

            ctxt->context->proximityPosition++;
            ctxt->context->node = nodeset->nodeTab[i];
            ctxt->context->doc = nodeset->nodeTab[i]->doc;

            subResult = xmlXPathCompiledEval(comp, ctxt->context);
            if (subResult != NULL) {
                switch (subResult->type) {
                    case XPATH_NODESET:
                        if (subResult->nodesetval != NULL)
                            for (j = 0; j < subResult->nodesetval->nodeNr;
                                 j++)
                                xmlXPathNodeSetAdd(ret->nodesetval,
                                                   subResult->nodesetval->
                                                   nodeTab[j]);
                        break;
                    case XPATH_BOOLEAN:
                        if (container != NULL) {
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "boolean",
                                            BAD_CAST (subResult->
                                            boolval ? "true" : ""));
                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
                    case XPATH_NUMBER:
                        if (container != NULL) {
                            xmlChar *val =
                                xmlXPathCastNumberToString(subResult->
                                                           floatval);
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "number", val);
                            if (val != NULL)
                                xmlFree(val);

                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
                    case XPATH_STRING:
                        if (container != NULL) {
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "string",
                                            subResult->stringval);
                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
		    default:
                        break;
                }
                xmlXPathFreeObject(subResult);
            }
        }
    }
    ctxt->context->doc = oldDoc;
    ctxt->context->node = oldNode;
    ctxt->context->contextSize = oldContextSize;
    ctxt->context->proximityPosition = oldProximityPosition;


  cleanup:
    
    if (comp != NULL)
        xmlXPathFreeCompExpr(comp);
    if (nodeset != NULL)
        xmlXPathFreeNodeSet(nodeset);
    if (str != NULL)
        xmlFree(str);
    valuePush(ctxt, ret);
    return;
}