static response_element_t *
parse_propfind_response (xmlTextReaderPtr reader)
{
	parser_strings_t    strings;
	response_element_t *elements;

	/* get internalized versions of some strings to avoid strcmp while
	 * parsing */
	strings.multistatus
		= xmlTextReaderConstString (reader, BAD_CAST "multistatus");
	strings.dav         = xmlTextReaderConstString (reader, BAD_CAST "DAV:");
	strings.href        = xmlTextReaderConstString (reader, BAD_CAST "href");
	strings.response    = xmlTextReaderConstString (reader, BAD_CAST "response");
	strings.propstat    = xmlTextReaderConstString (reader, BAD_CAST "propstat");
	strings.prop        = xmlTextReaderConstString (reader, BAD_CAST "prop");
	strings.getetag     = xmlTextReaderConstString (reader, BAD_CAST "getetag");

	while (xmlTextReaderRead (reader) == 1 && xmlTextReaderNodeType (reader) != XML_READER_TYPE_ELEMENT) {
	}

	if (xmlTextReaderConstLocalName (reader) != strings.multistatus
			|| xmlTextReaderConstNamespaceUri (reader) != strings.dav) {
		g_warning ("webdav PROPFIND result is not <DAV:multistatus>");
		return NULL;
	}

	elements = NULL;

	/* parse all DAV:response tags */
	while (xmlTextReaderRead (reader) == 1 && xmlTextReaderDepth (reader) > 0) {
		response_element_t *element;

		if (xmlTextReaderNodeType (reader) != XML_READER_TYPE_ELEMENT)
			continue;

		if (xmlTextReaderConstLocalName (reader) != strings.response
				|| xmlTextReaderConstNamespaceUri (reader) != strings.dav)
			continue;

		element = parse_response_tag (&strings, reader);
		if (element == NULL)
			continue;

		element->next = elements;
		elements      = element;
	}

	return elements;
}
예제 #2
0
int XMIResource::processElement(xmlTextReaderPtr reader)
{
    const xmlChar *name = xmlTextReaderConstLocalName(reader);
    parent = NB_XCOS_NAMES;

    // lookup for known node names
    // thanks to the string intern-ing, the pointer comparison could be used
    auto found = std::find(constXcosNames.begin(), constXcosNames.end(), name);
    enum xcosNames current = static_cast<enum xcosNames>(std::distance(constXcosNames.begin(), found));
    switch (current)
    {
        case e_Diagram:
        {
            // the root diagram should be decoded
            model::BaseObject o(root, DIAGRAM);

            processed.push_back(o);
            return loadDiagram(reader, o);
        }
        case e_child:
        {
            // this is a child of a diagram, resolve the type and call the loaders
            // iterate on attributes to lookup for EMF type

            // iterate on attributes
            for (int rc = xmlTextReaderMoveToFirstAttribute(reader); rc > 0; rc = xmlTextReaderMoveToNextAttribute(reader))
            {
                const xmlChar* nsURI  = xmlTextReaderConstNamespaceUri(reader);
                if (nsURI != xsiNamespaceUri)
                {
                    continue;
                }

                auto foundName = std::find(constXcosNames.begin(), constXcosNames.end(), xmlTextReaderConstLocalName(reader));
                enum xcosNames currentName = static_cast<enum xcosNames>(std::distance(constXcosNames.begin(), foundName));
                if (currentName != e_type)
                {
                    continue;
                }

                const xmlChar* value = xmlTextReaderConstValue(reader);
                const xmlChar* valueWithoutPrefix = BAD_CAST(std::strchr((const char*) value, ':'));
                if (valueWithoutPrefix == nullptr)
                {
                    valueWithoutPrefix = value;
                }
                else
                {
                    // remove the leading ':'
                    valueWithoutPrefix = valueWithoutPrefix + 1;
                }
                const xmlChar* interned = xmlTextReaderConstString(reader, valueWithoutPrefix);

                auto found = std::find(constXcosNames.begin(), constXcosNames.end(), interned);
                enum xcosNames current = static_cast<enum xcosNames>(std::distance(constXcosNames.begin(), found));
                switch (current)
                {
                    case e_Block:
                    {
                        ScicosID o = controller.createObject(BLOCK);

                        // assign the child
                        model::BaseObject parent = processed.back();
                        std::vector<ScicosID> children;
                        controller.getObjectProperty(parent.id(), parent.kind(), CHILDREN, children);
                        children.push_back(o);
                        controller.setObjectProperty(parent.id(), parent.kind(), CHILDREN, children);

                        model::BaseObject child(o, BLOCK);
                        processed.push_back(child);
                        return loadBlock(reader, child);
                    }
                    case e_Link:
                    {
                        ScicosID o = controller.createObject(LINK);

                        // assign the child
                        model::BaseObject parent = processed.back();
                        std::vector<ScicosID> children;
                        controller.getObjectProperty(parent.id(), parent.kind(), CHILDREN, children);
                        children.push_back(o);
                        controller.setObjectProperty(parent.id(), parent.kind(), CHILDREN, children);

                        model::BaseObject child(o, LINK);
                        processed.push_back(child);
                        return loadLink(reader, child);
                    }
                    case e_Annotation:
                    {
                        ScicosID o = controller.createObject(ANNOTATION);

                        // assign the child
                        model::BaseObject parent = processed.back();
                        std::vector<ScicosID> children;
                        controller.getObjectProperty(parent.id(), parent.kind(), CHILDREN, children);
                        children.push_back(o);
                        controller.setObjectProperty(parent.id(), parent.kind(), CHILDREN, children);

                        model::BaseObject child(o, ANNOTATION);
                        return loadAnnotation(reader, child);
                    }
                    default:
                        sciprint("Not handled child type=%s at line %d\n", *found,
                                 xmlTextReaderGetParserLineNumber(reader) - 1);
                        return -1;
                }
            }
            break;
        }
        case e_in: // no break on purpose
        case e_out: // no break on purpose
        case e_ein: // no break on purpose
        case e_eout:
        {
            ScicosID o = controller.createObject(PORT);

            enum object_properties_t p;
            switch (current)
            {
                case e_in:
                    p = INPUTS;
                    break;
                case e_out:
                    p = OUTPUTS;
                    break;
                case e_ein:
                    p = EVENT_INPUTS;
                    break;
                case e_eout:
                    p = EVENT_OUTPUTS;
                    break;
                default:
                    return -1;
            }

            model::BaseObject parent = processed.back();
            // add the port them to the parent
            std::vector<ScicosID> ports;
            controller.getObjectProperty(parent.id(), parent.kind(), p, ports);
            ports.push_back(o);
            controller.setObjectProperty(parent.id(), parent.kind(), p, ports);

            // decode content
            model::BaseObject child(o, PORT);
            return loadPort(reader, child);
        }
        case e_geometry:
            // geometry is used for rectangle coordinates of its parent
            return loadGeometry(reader, processed.back());
        case e_nzcross:
            // nzcross is a Block property
            if (!xmlTextReaderIsEmptyElement(reader))
            {
                parent = current;
            }
            return 1;
        case e_nmode:
            // nmode is a Block property
            if (!xmlTextReaderIsEmptyElement(reader))
            {
                parent = current;
            }
            return 1;
        case e_rpar:
            // rpar is a Block property
            if (!xmlTextReaderIsEmptyElement(reader))
            {
                parent = current;
            }
            return 1;
        case e_ipar:
            // ipar is a Block property
            if (!xmlTextReaderIsEmptyElement(reader))
            {
                parent = current;
            }
            return 1;
        case e_opar:
            // ipar is a Block property
            return loadBase64(reader, OPAR, processed.back());
        case e_state:
            // state is a Block property
            if (!xmlTextReaderIsEmptyElement(reader))
            {
                parent = current;
            }
            return 1;
        case e_dstate:
            // dstate is a Block property
            if (!xmlTextReaderIsEmptyElement(reader))
            {
                parent = current;
            }
            return 1;
        case e_odstate:
            // odstate is a Block property
            return loadBase64(reader, ODSTATE, processed.back());
        case e_equations:
            // equation is a Block property
            return loadBase64(reader, EQUATIONS, processed.back());
        case e_expression:
            // expression is a Block property
            if (!xmlTextReaderIsEmptyElement(reader))
            {
                parent = current;
            }
            return 1;
        case e_exprs:
            // exprs is a Block property
            return loadBase64(reader, EXPRS, processed.back());
        case e_controlPoint:
            // controlPoint is a link property
            return loadPoint(reader, processed.back());
        case e_context:
            // context is a Layer property
            if (!xmlTextReaderIsEmptyElement(reader))
            {
                parent = current;
            }
            return 1;
        case e_properties:
            // properties is a Diagram property
            return loadSimulationConfig(reader, processed.back());
        case e_datatype:
            // datatype is a Port property
            if (!xmlTextReaderIsEmptyElement(reader))
            {
                parent = current;
            }
            return 1;
        default:
            sciprint("Unknown \"%s\" element name at line %d\n", name, xmlTextReaderGetParserLineNumber(reader) - 1);
            return -1;
    }

    return 1;
}
예제 #3
0
int XMIResource::load(const char* uri)
{
    int ret;

    LibXML2State state;

    /*
     * Allocate the reader object, this API is used as it is simpler to use than SAX2 :
     *  * we have direct access to a node object
     *  * Strings are interned by libxml2
     *  * partial SAX2 callbacks are not supported by libxml2
     */
    xmlTextReaderPtr reader;
    /* resolve xinclude and intern strings */
    reader = xmlReaderForFile(uri, NULL, XML_PARSE_XINCLUDE | XML_PARSE_COMPACT);

    /*
     * Intern strings to speedup comparaison, this table can be generated using XPath on xcos.ecore .
     */
    constXcosNames[e_Annotation] = xmlTextReaderConstString(reader, BAD_CAST ("Annotation"));
    constXcosNames[e_BaseObject] = xmlTextReaderConstString(reader, BAD_CAST ("BaseObject"));
    constXcosNames[e_Block] = xmlTextReaderConstString(reader, BAD_CAST ("Block"));
    constXcosNames[e_CompiledRepresentation] = xmlTextReaderConstString(reader, BAD_CAST ("CompiledRepresentation"));
    constXcosNames[e_Diagram] = xmlTextReaderConstString(reader, BAD_CAST ("Diagram"));
    constXcosNames[e_Geometry] = xmlTextReaderConstString(reader, BAD_CAST ("Geometry"));
    constXcosNames[e_Layer] = xmlTextReaderConstString(reader, BAD_CAST ("Layer"));
    constXcosNames[e_Link] = xmlTextReaderConstString(reader, BAD_CAST ("Link"));
    constXcosNames[e_Point] = xmlTextReaderConstString(reader, BAD_CAST ("Point"));
    constXcosNames[e_Port] = xmlTextReaderConstString(reader, BAD_CAST ("Port"));
    constXcosNames[e_PortKind] = xmlTextReaderConstString(reader, BAD_CAST ("PortKind"));
    constXcosNames[e_SimulationConfig] = xmlTextReaderConstString(reader, BAD_CAST ("SimulationConfig"));
    constXcosNames[e_absoluteTolerance] = xmlTextReaderConstString(reader, BAD_CAST ("absoluteTolerance"));
    constXcosNames[e_base64] = xmlTextReaderConstString(reader, BAD_CAST ("base64"));
    constXcosNames[e_blocktype] = xmlTextReaderConstString(reader, BAD_CAST ("blocktype"));
    constXcosNames[e_child] = xmlTextReaderConstString(reader, BAD_CAST ("child"));
    constXcosNames[e_color] = xmlTextReaderConstString(reader, BAD_CAST ("color"));
    constXcosNames[e_connectedSignal] = xmlTextReaderConstString(reader, BAD_CAST ("connectedSignal"));
    constXcosNames[e_context] = xmlTextReaderConstString(reader, BAD_CAST ("context"));
    constXcosNames[e_controlPoint] = xmlTextReaderConstString(reader, BAD_CAST ("controlPoint"));
    constXcosNames[e_datatype] = xmlTextReaderConstString(reader, BAD_CAST ("datatype"));
    constXcosNames[e_debugLevel] = xmlTextReaderConstString(reader, BAD_CAST ("debugLevel"));
    constXcosNames[e_deltaH] = xmlTextReaderConstString(reader, BAD_CAST ("deltaH"));
    constXcosNames[e_deltaT] = xmlTextReaderConstString(reader, BAD_CAST ("deltaT"));
    constXcosNames[e_dependsOnT] = xmlTextReaderConstString(reader, BAD_CAST ("dependsOnT"));
    constXcosNames[e_dependsOnU] = xmlTextReaderConstString(reader, BAD_CAST ("dependsOnU"));
    constXcosNames[e_description] = xmlTextReaderConstString(reader, BAD_CAST ("description"));
    constXcosNames[e_destinationPort] = xmlTextReaderConstString(reader, BAD_CAST ("destinationPort"));
    constXcosNames[e_dstate] = xmlTextReaderConstString(reader, BAD_CAST ("dstate"));
    constXcosNames[e_ein] = xmlTextReaderConstString(reader, BAD_CAST ("ein"));
    constXcosNames[e_eout] = xmlTextReaderConstString(reader, BAD_CAST ("eout"));
    constXcosNames[e_equations] = xmlTextReaderConstString(reader, BAD_CAST ("equations"));
    constXcosNames[e_expression] = xmlTextReaderConstString(reader, BAD_CAST ("expression"));
    constXcosNames[e_exprs] = xmlTextReaderConstString(reader, BAD_CAST ("exprs"));
    constXcosNames[e_finalTime] = xmlTextReaderConstString(reader, BAD_CAST ("finalTime"));
    constXcosNames[e_firing] = xmlTextReaderConstString(reader, BAD_CAST ("firing"));
    constXcosNames[e_font] = xmlTextReaderConstString(reader, BAD_CAST ("font"));
    constXcosNames[e_fontSize] = xmlTextReaderConstString(reader, BAD_CAST ("fontSize"));
    constXcosNames[e_functionAPI] = xmlTextReaderConstString(reader, BAD_CAST ("functionAPI"));
    constXcosNames[e_functionName] = xmlTextReaderConstString(reader, BAD_CAST ("functionName"));
    constXcosNames[e_geometry] = xmlTextReaderConstString(reader, BAD_CAST ("geometry"));
    constXcosNames[e_height] = xmlTextReaderConstString(reader, BAD_CAST ("height"));
    constXcosNames[e_implicit] = xmlTextReaderConstString(reader, BAD_CAST ("implicit"));
    constXcosNames[e_in] = xmlTextReaderConstString(reader, BAD_CAST ("in"));
    constXcosNames[e_interfaceFunction] = xmlTextReaderConstString(reader, BAD_CAST ("interfaceFunction"));
    constXcosNames[e_ipar] = xmlTextReaderConstString(reader, BAD_CAST ("ipar"));
    constXcosNames[e_kind] = xmlTextReaderConstString(reader, BAD_CAST ("kind"));
    constXcosNames[e_label] = xmlTextReaderConstString(reader, BAD_CAST ("label"));
    constXcosNames[e_lineHeight] = xmlTextReaderConstString(reader, BAD_CAST ("lineHeight"));
    constXcosNames[e_lineWidth] = xmlTextReaderConstString(reader, BAD_CAST ("lineWidth"));
    constXcosNames[e_nmode] = xmlTextReaderConstString(reader, BAD_CAST ("nmode"));
    constXcosNames[e_nzcross] = xmlTextReaderConstString(reader, BAD_CAST ("nzcross"));
    constXcosNames[e_odstate] = xmlTextReaderConstString(reader, BAD_CAST ("odstate"));
    constXcosNames[e_opar] = xmlTextReaderConstString(reader, BAD_CAST ("opar"));
    constXcosNames[e_out] = xmlTextReaderConstString(reader, BAD_CAST ("out"));
    constXcosNames[e_parent] = xmlTextReaderConstString(reader, BAD_CAST ("parent"));
    constXcosNames[e_parentDiagram] = xmlTextReaderConstString(reader, BAD_CAST ("parentDiagram"));
    constXcosNames[e_path] = xmlTextReaderConstString(reader, BAD_CAST ("path"));
    constXcosNames[e_properties] = xmlTextReaderConstString(reader, BAD_CAST ("properties"));
    constXcosNames[e_realtimeScale] = xmlTextReaderConstString(reader, BAD_CAST ("realtimeScale"));
    constXcosNames[e_relativeTolerance] = xmlTextReaderConstString(reader, BAD_CAST ("relativeTolerance"));
    constXcosNames[e_rpar] = xmlTextReaderConstString(reader, BAD_CAST ("rpar"));
    constXcosNames[e_solver] = xmlTextReaderConstString(reader, BAD_CAST ("solver"));
    constXcosNames[e_sourceBlock] = xmlTextReaderConstString(reader, BAD_CAST ("sourceBlock"));
    constXcosNames[e_sourcePort] = xmlTextReaderConstString(reader, BAD_CAST ("sourcePort"));
    constXcosNames[e_state] = xmlTextReaderConstString(reader, BAD_CAST ("state"));
    constXcosNames[e_style] = xmlTextReaderConstString(reader, BAD_CAST ("style"));
    constXcosNames[e_timeTolerance] = xmlTextReaderConstString(reader, BAD_CAST ("timeTolerance"));
    constXcosNames[e_title] = xmlTextReaderConstString(reader, BAD_CAST ("title"));
    constXcosNames[e_type] = xmlTextReaderConstString(reader, BAD_CAST ("type"));
    constXcosNames[e_uid] = xmlTextReaderConstString(reader, BAD_CAST ("uid"));
    constXcosNames[e_version] = xmlTextReaderConstString(reader, BAD_CAST ("version"));
    constXcosNames[e_width] = xmlTextReaderConstString(reader, BAD_CAST ("width"));
    constXcosNames[e_x] = xmlTextReaderConstString(reader, BAD_CAST ("x"));
    constXcosNames[e_xcos] = xmlTextReaderConstString(reader, BAD_CAST ("xcos"));
    constXcosNames[e_y] = xmlTextReaderConstString(reader, BAD_CAST ("y"));

    xcosNamespaceUri = xmlTextReaderConstString(reader, BAD_CAST ("org.scilab.modules.xcos"));
    xsiNamespaceUri = xmlTextReaderConstString(reader, BAD_CAST ("http://www.w3.org/2001/XMLSchema-instance"));

    unresolved.clear();

    /*
     * Process the document
     */
    if (reader != NULL)
    {
        ret = xmlTextReaderRead(reader);
        while (ret == 1)
        {
            ret = processNode(reader);
            if (ret == 1)
            {
                ret = xmlTextReaderRead(reader);
            }
        }
        /*
         * Once the document has been fully parsed check the validation results
         */
        if (xmlTextReaderIsValid(reader) < 0)
        {
            sciprint("Document %s does not validate\n", uri);
        }
        xmlFreeTextReader(reader);
        if (ret < 0)
        {
            sciprint("%s : failed to parse\n", uri);
            return ret;
        }
    }
    else
    {
        sciprint("Unable to open %s\n", uri);
        return -1;
    }

    /*
     * After loading the XML file, resolve all references
     */
    for (const unresolvedReference& ref : unresolved)
    {
        auto it = references.find(ref.m_uid);
        if (it != references.end())
        {
            controller.setObjectProperty(ref.m_id, ref.m_kind, ref.m_prop, it->second);
        }
        else
        {
            sciprint("Unable to resolve %s\n", ref.m_uid.c_str());
            return -1;
        }
    }

    return ret;
}