mirror of https://github.com/BOINC/boinc.git
- Notices: put message bodies inside CDATA
- XML_PARSER: handle CDATA svn path=/trunk/boinc/; revision=20146
This commit is contained in:
parent
ee343cea02
commit
564cd7cece
|
@ -365,3 +365,13 @@ David 12 Jan 2010
|
|||
sched
|
||||
handle_request.cpp
|
||||
sched_types.cpp,h
|
||||
|
||||
David 12 Jan 2010
|
||||
- Notices: put message bodies inside CDATA
|
||||
- XML_PARSER: handle CDATA
|
||||
|
||||
client/
|
||||
cs_notice.cpp,h
|
||||
lib/
|
||||
notice.cpp
|
||||
parse.cpp,h
|
||||
|
|
|
@ -335,15 +335,14 @@ void NOTICES::prune() {
|
|||
}
|
||||
}
|
||||
|
||||
// write archive file for the RSS feed specified by URL
|
||||
// (or, if blank, non-RSS notices)
|
||||
// write archive file for the given RSS feed
|
||||
// (or, if NULL, non-RSS notices)
|
||||
//
|
||||
void NOTICES::write_archive(char* url) {
|
||||
char buf[256], path[256];
|
||||
void NOTICES::write_archive(RSS_FEED* rfp) {
|
||||
char path[256];
|
||||
|
||||
if (url) {
|
||||
escape_project_url(url, buf);
|
||||
sprintf(path, NOTICES_DIR"/archive_%s", buf);
|
||||
if (rfp) {
|
||||
rfp->archive_file_name(path);
|
||||
} else {
|
||||
strcpy(path, NOTICES_DIR"/archive.xml");
|
||||
}
|
||||
|
@ -355,8 +354,8 @@ void NOTICES::write_archive(char* url) {
|
|||
if (!f) return;
|
||||
for (unsigned int i=0; i<notices.size(); i++) {
|
||||
NOTICE& n = notices[i];
|
||||
if (url) {
|
||||
if (strcmp(url, n.feed_url)) continue;
|
||||
if (rfp) {
|
||||
if (strcmp(rfp->url, n.feed_url)) continue;
|
||||
} else {
|
||||
if (strlen(n.feed_url)) continue;
|
||||
}
|
||||
|
@ -388,13 +387,13 @@ void NOTICES::write(int seqno, MIOFILE& fout, bool public_only) {
|
|||
|
||||
void RSS_FEED::feed_file_name(char* path) {
|
||||
char buf[256];
|
||||
escape_project_url(url, buf);
|
||||
escape_project_url(url_base, buf);
|
||||
sprintf(path, NOTICES_DIR"/%s", buf);
|
||||
}
|
||||
|
||||
void RSS_FEED::archive_file_name(char* path) {
|
||||
char buf[256];
|
||||
escape_project_url(url, buf);
|
||||
escape_project_url(url_base, buf);
|
||||
sprintf(path, NOTICES_DIR"/archive_%s", buf);
|
||||
}
|
||||
|
||||
|
@ -428,6 +427,9 @@ int RSS_FEED::parse_desc(XML_PARSER& xp) {
|
|||
}
|
||||
return ERR_XML_PARSE;
|
||||
}
|
||||
strcpy(url_base, url);
|
||||
char* p = strchr(url_base, '?');
|
||||
if (p) *p = 0;
|
||||
return 0;
|
||||
}
|
||||
if (xp.parse_str(tag, "url", url, sizeof(url))) continue;
|
||||
|
@ -462,15 +464,25 @@ int RSS_FEED::parse_items(XML_PARSER& xp, int& nitems) {
|
|||
char tag[256];
|
||||
bool is_tag;
|
||||
nitems = 0;
|
||||
int ntotal = 0, nerror = 0;
|
||||
while (!xp.get(tag, sizeof(tag), is_tag)) {
|
||||
if (!is_tag) continue;
|
||||
if (!strcmp(tag, "/rss")) {
|
||||
if (log_flags.notice_debug) {
|
||||
msg_printf(0, MSG_INFO,
|
||||
"[notice_debug] parsed RSS feed: total %d error %d added %d",
|
||||
ntotal, nerror, nitems
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(tag, "item")) {
|
||||
NOTICE n;
|
||||
ntotal++;
|
||||
int retval = n.parse_rss(xp);
|
||||
if (!retval) {
|
||||
if (retval) {
|
||||
nerror++;
|
||||
} else {
|
||||
n.arrival_time = gstate.now;
|
||||
strcpy(n.feed_url, url);
|
||||
if (notices.append_unique(n)) {
|
||||
|
@ -559,7 +571,7 @@ void RSS_FEED_OP::handle_reply(int http_op_retval) {
|
|||
fclose(f);
|
||||
|
||||
if (nitems) {
|
||||
notices.write_archive(rfp->url);
|
||||
notices.write_archive(rfp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ struct NOTICES {
|
|||
void init();
|
||||
void init_rss();
|
||||
int read_archive_file(char* file, char* feed_url);
|
||||
void write_archive(char* url);
|
||||
void write_archive(struct RSS_FEED*);
|
||||
void prune();
|
||||
};
|
||||
|
||||
|
@ -81,6 +81,7 @@ extern NOTICES notices;
|
|||
|
||||
struct RSS_FEED {
|
||||
char url[256];
|
||||
char url_base[256];
|
||||
double poll_interval;
|
||||
double next_poll_time;
|
||||
bool use_seqno;
|
||||
|
|
|
@ -67,7 +67,7 @@ void NOTICE::write(MIOFILE& f, bool for_gui) {
|
|||
f.printf(
|
||||
"<notice>\n"
|
||||
" <title>%s</title>\n"
|
||||
" <description>%s</description>\n"
|
||||
" <description><![CDATA[\n%s\n]]></description>\n"
|
||||
" <create_time>%f</create_time>\n"
|
||||
" <arrival_time>%f</arrival_time>\n"
|
||||
" <is_private>%d</is_private>\n"
|
||||
|
|
|
@ -464,16 +464,20 @@ bool XML_PARSER::scan_nonws(int& first_char) {
|
|||
}
|
||||
}
|
||||
|
||||
#define XML_PARSE_COMMENT 1
|
||||
#define XML_PARSE_EOF 2
|
||||
#define XML_PARSE_CDATA 3
|
||||
|
||||
int XML_PARSER::scan_comment() {
|
||||
char buf[256];
|
||||
char* p = buf;
|
||||
while (1) {
|
||||
int c = f->_getc();
|
||||
if (c == EOF) return 2;
|
||||
if (c == EOF) return XML_PARSE_EOF;
|
||||
*p++ = c;
|
||||
*p = 0;
|
||||
if (strstr(buf, "-->")) {
|
||||
return 1;
|
||||
return XML_PARSE_COMMENT;
|
||||
}
|
||||
if (strlen(buf) > 32) {
|
||||
strcpy(buf, buf+16);
|
||||
|
@ -482,6 +486,27 @@ int XML_PARSER::scan_comment() {
|
|||
}
|
||||
}
|
||||
|
||||
int XML_PARSER::scan_cdata(char* buf, int len) {
|
||||
char* p = buf;
|
||||
len--;
|
||||
while (1) {
|
||||
int c = f->_getc();
|
||||
if (c == EOF) return XML_PARSE_EOF;
|
||||
if (len) {
|
||||
*p++ = c;
|
||||
len--;
|
||||
}
|
||||
if (c == '>') {
|
||||
*p = 0;
|
||||
char* q = strstr(buf, "]]>");
|
||||
if (q) {
|
||||
*q = 0;
|
||||
return XML_PARSE_CDATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we just read a <; read until we find a >.
|
||||
// Given <tag [attr=val attr=val] [/]>:
|
||||
// - copy tag (or tag/) to tag_buf
|
||||
|
@ -493,11 +518,13 @@ int XML_PARSER::scan_comment() {
|
|||
// 2 if reached EOF
|
||||
//
|
||||
int XML_PARSER::scan_tag(
|
||||
char* tag_buf, int tag_len, char* attr_buf, int attr_len
|
||||
char* tag_buf, int _tag_len, char* attr_buf, int attr_len
|
||||
) {
|
||||
int c;
|
||||
char* buf_start = tag_buf;
|
||||
bool found_space = false;
|
||||
int tag_len = _tag_len;
|
||||
|
||||
for (int i=0; ; i++) {
|
||||
c = f->_getc();
|
||||
if (c == EOF) return 2;
|
||||
|
@ -536,6 +563,9 @@ int XML_PARSER::scan_tag(
|
|||
if (i==2 && !strncmp(buf_start, "!--", 3)) {
|
||||
return scan_comment();
|
||||
}
|
||||
if (i==7 && !strncmp(buf_start, "![CDATA[", 8)) {
|
||||
return scan_cdata(buf_start, tag_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,9 +602,13 @@ bool XML_PARSER::get(char* buf, int len, bool& is_tag, char* attr_buf, int attr_
|
|||
if (eof) return true;
|
||||
if (c == '<') {
|
||||
int retval = scan_tag(buf, len, attr_buf, attr_len);
|
||||
if (retval == 2) return true;
|
||||
if (retval == 1) continue;
|
||||
is_tag = true;
|
||||
if (retval == XML_PARSE_EOF) return true;
|
||||
if (retval == XML_PARSE_COMMENT) continue;
|
||||
if (retval == XML_PARSE_CDATA) {
|
||||
is_tag = false;
|
||||
} else {
|
||||
is_tag = true;
|
||||
}
|
||||
} else {
|
||||
buf[0] = c;
|
||||
eof = copy_until_tag(buf+1, len-1);
|
||||
|
|
|
@ -29,6 +29,7 @@ class XML_PARSER {
|
|||
bool scan_nonws(int&);
|
||||
int scan_comment();
|
||||
int scan_tag(char*, int, char* ab=0, int al=0);
|
||||
int scan_cdata(char*, int);
|
||||
bool copy_until_tag(char*, int);
|
||||
public:
|
||||
MIOFILE* f;
|
||||
|
|
Loading…
Reference in New Issue