XmlNode Protocol::goto_doc_node ( const XmlNode& node ) { XmlNode fnode(node); if( !fnode.is_valid() ) throw XmlError(FromHere(), "Node is not valid"); if ( fnode.content->type() == rapidxml::node_document ) { fnode.content = fnode.content->first_node(); if ( !fnode.is_valid() ) throw XmlError( FromHere(), "XML document is empty" ); } if ( fnode.content->type() == rapidxml::node_document ) { fnode.content = fnode.content->next_sibling(); if ( !fnode.is_valid() ) throw XmlError( FromHere(), "No xml nodes after declaration" ); } // find the first doc node if ( strcmp(fnode.content->name() , Tags::node_doc()) ) /* are not equal */ fnode.content = fnode.content->next_sibling( Tags::node_doc() ); if ( !fnode.is_valid() ) throw common::XmlError( FromHere(), "No xml doc found" ); return fnode; }
void XmlView::Load(int parent, XmlParser& p) { if(p.IsTag()) { String tag = p.ReadTag(); String txt = tag; for(int i = 0; i < p.GetAttrCount(); i++) txt << ' ' << p.GetAttr(i) << "=\"" << p[i] << "\""; parent = xml.Add(parent, XmlImg::Tag(), tag, txt); while(!p.End()) { if(p.IsEof()) throw XmlError(""); Load(parent, p); } } else if(p.IsText()) xml.Add(parent, XmlImg::Text(), Null, NormalizeSpaces(p.ReadText())); else if(p.IsPI()) xml.Add(parent, XmlImg::PI(), Null, NormalizeSpaces(p.ReadPI())); else if(p.IsDecl()) xml.Add(parent, XmlImg::Decl(), Null, NormalizeSpaces(p.ReadDecl())); else if(p.IsComment()) xml.Add(parent, XmlImg::Comment(), Null, NormalizeSpaces(p.ReadComment())); else NEVER(); }
void XmlParser::Skip() { if(IsEof()) throw XmlError("Unexpected end of file"); if(cdata.GetCount() && type != XML_TEXT) cdata.Clear(); else if(IsTag()) { String n = ReadTag(); while(!End()) { if(IsEof()) throw XmlError("Unexpected end of file expected when skipping tag \'" + n + "\'"); Skip(); } } else Next(); }
String XmlParser::ReadPI(bool next) { if(!IsPI()) throw XmlError("Processing info expected"); String h = tagtext; if(next) Next(); return h; }
String XmlParser::ReadComment(bool next) { if(!IsComment()) throw XmlError("Comment expected"); String h = tagtext; if(next) Next(); return h; }
String XmlParser::ReadDecl(bool next) { if(!IsDecl()) throw XmlError("Declaration expected"); String h = tagtext; if(next) Next(); return h; }
bool XmlParser::End() { if(IsEof()) throw XmlError("Unexpected end of file"); if(IsEnd()) { LLOG("EndTag " << text); if(stack.IsEmpty()) throw XmlError(NFormat("Unexpected end-tag: </%s>", tagtext)); if(stack.Top().tag != tagtext && !relaxed) { LLOG("Tag/end-tag mismatch: <" << stack.Top().tag << "> </" << tagtext << ">"); throw XmlError(NFormat("Tag/end-tag mismatch: <%s> </%s>", stack.Top().tag, tagtext)); } stack.Drop(); npreserve = (!stack.IsEmpty() && stack.Top().preserve_blanks); Next(); return true; } return false; }
String XmlParser::ReadTag(bool next) { if(type != XML_TAG) throw XmlError("Expected tag"); LLOG("ReadTag " << text); String h = tagtext; if(next) { stack.Add(Nesting(h, npreserve)); attr = nattr; attr1 = nattr1; attrval1 = nattrval1; Next(); } return h; }
/** * Parse the given buffer and fills the given Document object with its contents. * Throws XmlError on parsing errors. * * The document that is passed in will be reset before being filled if not empty. * * @param pvBuf in: memory buffer to parse. * @param cbSize in: size of the memory buffer. * @param strFilename in: name fo file to parse. * @param doc out: document to be reset and filled with data according to file contents. */ void XmlMemParser::read(const void* pvBuf, size_t cbSize, const RTCString &strFilename, Document &doc) { GlobalLock lock; // global.setExternalEntityLoader(ExternalEntityLoader); const char *pcszFilename = strFilename.c_str(); doc.m->reset(); if (!(doc.m->plibDocument = xmlCtxtReadMemory(m_ctxt, (const char*)pvBuf, (int)cbSize, pcszFilename, NULL, // encoding = auto XML_PARSE_NOBLANKS | XML_PARSE_NONET))) throw XmlError(xmlCtxtGetLastError(m_ctxt)); doc.refreshInternals(); }
/** * Reads the given file and fills the given Document object with its contents. * Throws XmlError on parsing errors. * * The document that is passed in will be reset before being filled if not empty. * * @param strFilename in: name fo file to parse. * @param doc out: document to be reset and filled with data according to file contents. */ void XmlFileParser::read(const RTCString &strFilename, Document &doc) { GlobalLock lock; // global.setExternalEntityLoader(ExternalEntityLoader); m->strXmlFilename = strFilename; const char *pcszFilename = strFilename.c_str(); ReadContext context(pcszFilename); doc.m->reset(); if (!(doc.m->plibDocument = xmlCtxtReadIO(m_ctxt, ReadCallback, CloseCallback, &context, pcszFilename, NULL, // encoding = auto XML_PARSE_NOBLANKS | XML_PARSE_NONET))) throw XmlError(xmlCtxtGetLastError(m_ctxt)); doc.refreshInternals(); }
SignalFrame SignalFrame::create_reply ( const URI & sender ) { cf3_assert ( node.is_valid() ); URI sender_uri(sender); // if the sender parameter is not valid, we use the one of the signal if( sender_uri.scheme() != URI::Scheme::CPATH || sender_uri.path().empty()) { rapidxml::xml_attribute<>* attr = node.content->first_attribute("receiver"); if(attr == nullptr) throw XmlError(FromHere(), "Could not find a sender"); sender_uri = URI(attr->value()); } SignalFrame reply(Protocol::add_reply_frame( node )); reply.node.set_attribute("sender", sender_uri.string() ); return reply; }
void CJournal::execute_signals (const boost::filesystem::path & filename) { if (m_root.expired()) throw IllegalCall(FromHere(), "Component \'" + name() + "\' has no root"); boost::shared_ptr<XmlDoc> xmldoc = XML::parse_file(filename); XmlNode doc_node = Protocol::goto_doc_node(*xmldoc.get()); // rapidxml::xml_node * signals_map = doc_node.content->first_node(); // bool found_map = false; rapidxml::xml_node<>* node = nullptr; // rapidxml::xml_attribute<>* key_attr = nullptr; CRoot& root = Core::instance().root(); const char * frame_tag = Protocol::Tags::node_frame(); XmlNode signal_map = Map(doc_node).find_value( Protocol::Tags::key_signals() ); // for( ; signals_map != nullptr ; signals_map = signals_map->next_sibling()) // { // key_attr = signals_map->first_attribute("key"); // found_map = key_attr != nullptr && std::strcmp(key_attr->value(), "signals") == 0; // if(found_map) // break; // } if( !signal_map.is_valid() ) throw XmlError(FromHere(), "Could not find \'signals\' map."); node = signal_map.content->first_node( frame_tag ); for( ; node != nullptr ; node = node->next_sibling(frame_tag) ) { rapidxml::xml_attribute<>* type_attr = node->first_attribute("type"); if(type_attr != nullptr && std::strcmp(type_attr->value(), "signal") == 0) { rapidxml::xml_attribute<>* target_attr = node->first_attribute("target"); rapidxml::xml_attribute<>* receiver_attr = node->first_attribute("receiver"); std::string target = target_attr != nullptr ? target_attr->value() : ""; std::string receiver = receiver_attr != nullptr ? receiver_attr->value() : ""; if(target.empty()) CFwarn << "Warning: missing or empty target. Skipping this signal." << CFendl; if(receiver.empty()) CFwarn << "Warning: missing or empty receiver. Skipping this signal." << CFendl; if(receiver == "//Root/Core") // server specific component continue; try { SignalFrame sf(node); root.retrieve_component(receiver)->call_signal(target, sf); } catch(Exception & e) { CFerror << e.what() << CFendl; } } } }
void XmlParser::PassEnd() { if(!End()) throw XmlError(String().Cat() << "Expected \'" << (stack.GetCount() ? stack.Top().tag : String()) << "\' end-tag"); }
void XmlParser::PassTag(const String& tag) { if(!Tag(tag)) throw XmlError(String().Cat() << '\'' << tag << "'\' tag expected"); }
void XmlParser::Next() { nattr.Clear(); nattr1 = nattrval1 = Null; if(empty_tag) { empty_tag = false; type = XML_END; return; } type = Null; StringBuffer raw_text; for(;;) { if(*term == '\0') { type = XML_EOF; return; } if(*term == '<') { if(term[1] == '!' && term[2] == '[' && term[3] == 'C' && term[4] == 'D' && term[5] == 'A' && term[6] == 'T' && term[7] == 'A' && term[8] == '[') { // ![CDATA[ term += 9; for(;;) { if(*term == '\0') throw XmlError("Unterminated CDATA"); if(term[0] == ']' && term[1] == ']' && term[2] == '>') { // ]]> term += 3; break; } if(*term == '\n') line++; raw_text.Cat(*term++); } type = XML_TEXT; continue; } else break; } if(*term == '\n') line++; if(*term == '&') { Ent(raw_text); type = XML_TEXT; } else { if((byte)*term > ' ') type = XML_TEXT; raw_text.Cat(*term++); } } cdata = FromUtf8(String(raw_text)).ToString(); if(cdata.GetCount() && (npreserve || preserveall)) type = XML_TEXT; if(type == XML_TEXT) return; term++; if(*term == '!') { type = XML_DECL; term++; if(term[0] == '-' && term[1] == '-') { type = XML_COMMENT; term += 2; for(;;) { if(term[0] == '-' && term[1] == '-' && term[2] == '>') break; if(*term == '\0') throw XmlError("Unterminated comment"); if(*term == '\n') line++; tagtext.Cat(*term++); } term += 3; return; } bool intdt = false; for(;;) { if (*term == '[') intdt = true; if(*term == '>' && intdt == false) { term++; break; } if(intdt == true && term[0] == ']' && term[1] == '>') { tagtext.Cat(*term++); term++; break; } if(*term == '\0') throw XmlError("Unterminated declaration"); if(*term == '\n') line++; tagtext.Cat(*term++); } } else if(*term == '?') { type = XML_PI; term++; for(;;) { if(term[0] == '?' && term[1] == '>') { term += 2; return; } if(*term == '\0') throw XmlError("Unterminated processing info"); if(*term == '\n') line++; tagtext.Cat(*term++); } } else if(*term == '/') { type = XML_END; term++; const char *t = term; while(IsXmlNameChar(*term)) term++; tagtext = String(t, term); if(*term != '>') throw XmlError("Unterminated end-tag"); term++; } else { type = XML_TAG; const char *t = term; while(IsXmlNameChar(*term)) term++; tagtext = String(t, term); for(;;) { SkipWhites(); if(*term == '>') { term++; break; } if(term[0] == '/' && term[1] == '>') { cdata.Clear(); empty_tag = true; term += 2; break; } if(*term == '\0') throw XmlError("Unterminated tag"); const char *t = term++; while((byte)*term > ' ' && *term != '=' && *term != '>') term++; String attr(t, term); SkipWhites(); if(*term == '=') { term++; SkipWhites(); StringBuffer attrval; if(*term == '\"') ReadAttr(attrval, '\"'); else if(*term == '\'') ReadAttr(attrval, '\''); else while((byte)*term > ' ' && *term != '>' && *term != '/') if(*term == '&') Ent(attrval); else { const char *e = term; while((byte)*++e > ' ' && *e != '>' && *e != '&') ; attrval.Cat(term,(int) (e - term)); term = e; } if(attr == "xml:space" && attrval.GetLength() == 8 && !memcmp(~attrval, "preserve", 8)) npreserve = true; String aval = FromUtf8(~attrval, attrval.GetLength()).ToString(); if(IsNull(nattr1)) { nattr1 = attr; nattrval1 = aval; } else nattr.Add(attr, aval); } } } }
NAMESPACE_UPP Value ParseXmlRpcValue(XmlParser& p) { Value r; p.PassTag("value"); if(p.Tag("int") || p.Tag("i4")) { String s = p.ReadText(); CParser p(s); if(!p.IsInt()) throw XmlError("integer expected"); r = p.ReadInt(); } else if(p.Tag("boolean")) { int n = StrInt(p.ReadText()); if(n != 0 && n != 1) throw XmlError("boolean expected"); r = (bool)n; } else if(p.Tag("double")) { String s = p.ReadText(); CParser p(s); if(!p.IsDouble()) throw XmlError("double expected"); r = p.ReadDouble(); } else if(p.Tag("string") || p.Tag("base64")) r = p.ReadText(); else if(p.TagE("nil")) { p.PassEnd(); return r; } else if(p.Tag("dateTime.iso8601")) { String s = TrimBoth(p.ReadText()); // 19980717T14:08:55 // 01234567890123456 if(s.GetCount() != 17 || s[8] != 'T' || s[11] != ':' || s[14] != ':') throw XmlError("invalid dateTime format"); Time tm; tm.year = atoi(s.Mid(0, 4)); tm.month = atoi(s.Mid(4, 2)); tm.day = atoi(s.Mid(6, 2)); tm.hour = atoi(s.Mid(9, 2)); tm.minute = atoi(s.Mid(12, 2)); tm.second = atoi(s.Mid(15, 2)); r = tm; } else if(p.Tag("array")) { ValueArray va; p.PassTag("data"); while(!p.End()) va.Add(ParseXmlRpcValue(p)); r = va; } else if(p.Tag("struct")) { ValueMap vm; while(p.Tag("member")) { p.PassTag("name"); String name = p.ReadText(); p.PassEnd(); vm.Add((Value)name, ParseXmlRpcValue(p)); p.PassEnd(); } r = vm; } else throw XmlError("unknown value type"); p.PassEnd(); p.PassEnd(); return r; }