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; }
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; }
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; }