// This is to parse our own XML. // parse_rss() parses an RSS feed item. // int NOTICE::parse(XML_PARSER& xp) { clear(); while (!xp.get_tag()) { if (!xp.is_tag) continue; if (xp.match_tag("/notice")) { if (strcasestr(description.c_str(), "youtube.com")) { is_youtube_video = true; } return 0; } if (xp.parse_int("seqno", seqno)) continue; if (xp.parse_str("title", title, sizeof(title))) continue; if (xp.parse_string("description", description)) { xml_unescape(description); // 2nd pass continue; } if (xp.parse_double("create_time", create_time)) continue; if (xp.parse_double("arrival_time", arrival_time)) continue; if (xp.parse_bool("is_private", is_private)) continue; if (xp.parse_str("category", category, sizeof(category))) continue; if (xp.parse_str("link", link, sizeof(link))) continue; if (xp.parse_str("project_name", project_name, sizeof(project_name))) continue; if (xp.parse_str("guid", guid, sizeof(guid))) continue; if (xp.parse_str("feed_url", feed_url, sizeof(feed_url))) continue; } return ERR_XML_PARSE; }
// Note: XML unescaping never increases string length // void xml_unescape(std::wstring& in) { size_t n = in.size()+1; wxChar* buf = (wxChar*)malloc(n*sizeof(wxChar)); _tcscpy(buf, in.c_str()); xml_unescape(buf); in = buf; free(buf); }
boolean xml_parse_attributes (const char **cpp, unsigned max, char *attrs) { boolean rc = TRUE; unsigned num; char *cp, *ep, *np; char quote; for (num = 0; attrs && *attrs && num < max; cp = attrs) { cp = strtrimws(attrs); if (*cp == 0) { rc = FALSE; break; } ep = strchr(cp, '='); if (ep == NULL) break; /* Strike over trailing space */ np = strtrimtailws(ep - 1, cp); np[ 1 ] = 0; ep += 1; /* Step over '=' */ ep = strtrimws(ep); /* Step over leading ws */ if (*ep == '\'' || *ep == '"') quote = *ep; else break; /* Possible end-of-input */ ep += 1; /* Skip over quote */ np = strchr(ep, quote); if (np == NULL) break; attrs = np[ 1 ] ? np + 1 : NULL; *np = 0; if (xml_unescape(ep, np - ep + 1, ep, TRUE)) break; cpp[ num++ ] = cp; cpp[ num++ ] = ep; if (attrs == NULL) { rc = FALSE; break; } } if (num < max) cpp[ num ] = NULL; return rc; }
// We just parsed "parsed_tag". // If it matches "start_tag", and is followed by a string // and by the matching close tag, return the string in "buf", // and return true. // bool XML_PARSER::parse_str(const wxChar* start_tag, wxChar* buf, int len) { bool eof; wxChar end_tag[256], tag[256]; // handle the archaic form <tag/>, which means empty string // size_t n = _tcslen(parsed_tag); if (parsed_tag[n-1] == wxT('/')) { _tcscpy(tag, parsed_tag); tag[n-1] = 0; if (!_tcscmp(tag, start_tag)) { _tcscpy(buf, wxT("")); return true; } } // check for start tag // if (_tcscmp(parsed_tag, start_tag)) return false; end_tag[0] = '/'; _tcscpy(end_tag+1, start_tag); // get text after start tag // int retval = get_aux(buf, len, 0, 0); if (retval == XML_PARSE_EOF) return false; // if it's the end tag, return empty string // if (retval == XML_PARSE_TAG) { if (_tcscmp(buf, end_tag)) { return false; } else { _tcscpy(buf, wxT("")); return true; } } eof = get(tag, sizeof(tag), is_tag); if (eof) return false; if (!is_tag) return false; if (_tcscmp(tag, end_tag)) return false; if (retval != XML_PARSE_CDATA) { xml_unescape(buf); } return true; }
int ACCT_MGR_INFO::parse_login_file(FILE* p) { MIOFILE mf; int retval; mf.init_file(p); XML_PARSER xp(&mf); if (!xp.parse_start("acct_mgr_login")) { msg_printf(NULL, MSG_INTERNAL_ERROR, "missing start tag in account manager login file" ); } while (!xp.get_tag()) { if (!xp.is_tag) { printf("unexpected text: %s\n", xp.parsed_tag); continue; } if (xp.match_tag("/acct_mgr_login")) break; if (xp.parse_str("login", login_name, 256)) continue; if (xp.parse_str("password_hash", password_hash, 256)) continue; if (xp.parse_str("authenticator", authenticator, 256)) continue; if (xp.parse_str("previous_host_cpid", previous_host_cpid, sizeof(previous_host_cpid))) continue; if (xp.parse_double("next_rpc_time", next_rpc_time)) continue; if (xp.match_tag("opaque")) { retval = xp.element_contents("</opaque>", opaque, sizeof(opaque)); if (retval) { msg_printf(NULL, MSG_INFO, "error parsing <opaque> in acct_mgr_login.xml" ); } continue; } if (xp.parse_str("user_name", user_name, sizeof(user_name))) { xml_unescape(user_name); continue; } if (xp.parse_str("team_name", team_name, sizeof(team_name))) { xml_unescape(team_name); continue; } if (xp.parse_bool("no_project_notices", no_project_notices)) continue; if (xp.parse_bool("dynamic", dynamic)) continue; if (xp.match_tag("user_keywords")) { retval = user_keywords.parse(xp); if (retval) { msg_printf(NULL, MSG_INFO, "error parsing user keywords in acct_mgr_login.xml" ); } continue; } if (log_flags.unparsed_xml) { msg_printf(NULL, MSG_INFO, "[unparsed_xml] unrecognized %s in acct_mgr_login.xml", xp.parsed_tag ); } xp.skip_unexpected( log_flags.unparsed_xml, "ACCT_MGR_INFO::parse_login_file" ); } return 0; }
// parse RPC reply from account manager // int ACCT_MGR_OP::parse(FILE* f) { string message; int retval; MIOFILE mf; mf.init_file(f); XML_PARSER xp(&mf); accounts.clear(); error_str = ""; error_num = 0; repeat_sec = 0; safe_strcpy(host_venue, ""); safe_strcpy(ami.opaque, ""); ami.no_project_notices = false; ami.dynamic = false; rss_feeds.clear(); if (!xp.parse_start("acct_mgr_reply")) return ERR_XML_PARSE; while (!xp.get_tag()) { if (!xp.is_tag) { if (log_flags.unparsed_xml) { msg_printf(0, MSG_INFO, "[unparsed_xml] ACCT_MGR_OP::parse: unexpected text %s", xp.parsed_tag ); } continue; } if (xp.match_tag("/acct_mgr_reply")) return 0; if (xp.parse_str("name", ami.project_name, 256)) continue; if (xp.parse_str("user_name", ami.user_name, sizeof(ami.user_name))) { xml_unescape(ami.user_name); continue; } if (xp.parse_str("team_name", ami.team_name, sizeof(ami.team_name))) { xml_unescape(ami.team_name); continue; } if (xp.parse_str("authenticator", ami.authenticator, 256)) continue; if (xp.parse_int("error_num", error_num)) continue; if (xp.parse_string("error", error_str)) continue; if (xp.parse_string("error_msg", error_str)) continue; if (xp.parse_double("repeat_sec", repeat_sec)) continue; if (xp.parse_bool("dynamic", ami.dynamic)) continue; if (xp.parse_string("message", message)) { msg_printf(NULL, MSG_INFO, "Account manager: %s", message.c_str()); continue; } if (xp.match_tag("opaque")) { retval = xp.element_contents("</opaque>", ami.opaque, sizeof(ami.opaque)); if (retval) return retval; continue; } if (xp.match_tag("signing_key")) { retval = xp.element_contents("</signing_key>", ami.signing_key, sizeof(ami.signing_key)); if (retval) return retval; continue; } if (xp.match_tag("account")) { AM_ACCOUNT account; retval = account.parse(xp); if (retval) { msg_printf(NULL, MSG_INTERNAL_ERROR, "Can't parse account in account manager reply: %s", boincerror(retval) ); } else { accounts.push_back(account); } continue; } if (xp.match_tag("global_preferences")) { retval = copy_element_contents( f, "</global_preferences>", global_prefs_xml ); if (retval) { msg_printf(NULL, MSG_INTERNAL_ERROR, "Can't parse global prefs in account manager reply: %s", boincerror(retval) ); return retval; } continue; } if (xp.parse_str("host_venue", host_venue, sizeof(host_venue))) { continue; } if (xp.match_tag("rss_feeds")) { got_rss_feeds = true; parse_rss_feed_descs(xp, rss_feeds); continue; } if (xp.parse_bool("no_project_notices", ami.no_project_notices)) { continue; } if (xp.match_tag("user_keywords")) { retval = ami.user_keywords.parse(xp); if (retval) return retval; continue; } if (log_flags.unparsed_xml) { msg_printf(NULL, MSG_INFO, "[unparsed_xml] ACCT_MGR_OP::parse: unrecognized tag <%s>", xp.parsed_tag ); } xp.skip_unexpected(log_flags.unparsed_xml, "ACCT_MGR_OP::parse"); } return ERR_XML_PARSE; }