📄 xml.c
字号:
(*svn_parser->end_handler)(svn_parser->baton, name);}static void expat_data_handler(void *userData, const XML_Char *s, int len){ svn_xml_parser_t *svn_parser = userData; (*svn_parser->data_handler)(svn_parser->baton, s, (apr_size_t)len);}/*** Making a parser. ***/svn_xml_parser_t *svn_xml_make_parser(void *baton, svn_xml_start_elem start_handler, svn_xml_end_elem end_handler, svn_xml_char_data data_handler, apr_pool_t *pool){ svn_xml_parser_t *svn_parser; apr_pool_t *subpool; XML_Parser parser = XML_ParserCreate(NULL); XML_SetElementHandler(parser, start_handler ? expat_start_handler : NULL, end_handler ? expat_end_handler : NULL); XML_SetCharacterDataHandler(parser, data_handler ? expat_data_handler : NULL); /* ### we probably don't want this pool; or at least we should pass it ### to the callbacks and clear it periodically. */ subpool = svn_pool_create(pool); svn_parser = apr_pcalloc(subpool, sizeof(*svn_parser)); svn_parser->parser = parser; svn_parser->start_handler = start_handler; svn_parser->end_handler = end_handler; svn_parser->data_handler = data_handler; svn_parser->baton = baton; svn_parser->pool = subpool; /* store our parser info as the UserData in the Expat parser */ XML_SetUserData(parser, svn_parser); return svn_parser;}/* Free a parser */voidsvn_xml_free_parser(svn_xml_parser_t *svn_parser){ /* Free the expat parser */ XML_ParserFree(svn_parser->parser); /* Free the subversion parser */ svn_pool_destroy(svn_parser->pool);}svn_error_t *svn_xml_parse(svn_xml_parser_t *svn_parser, const char *buf, apr_size_t len, svn_boolean_t is_final){ svn_error_t *err; int success; /* Parse some xml data */ success = XML_Parse(svn_parser->parser, buf, len, is_final); /* If expat choked internally, return its error. */ if (! success) { err = svn_error_createf (SVN_ERR_XML_MALFORMED, NULL, _("Malformed XML: %s at line %d"), XML_ErrorString(XML_GetErrorCode(svn_parser->parser)), XML_GetCurrentLineNumber(svn_parser->parser)); /* Kill all parsers and return the expat error */ svn_xml_free_parser(svn_parser); return err; } /* Did an error occur somewhere *inside* the expat callbacks? */ if (svn_parser->error) { err = svn_parser->error; svn_xml_free_parser(svn_parser); return err; } return SVN_NO_ERROR;}void svn_xml_signal_bailout(svn_error_t *error, svn_xml_parser_t *svn_parser){ /* This will cause the current XML_Parse() call to finish quickly! */ XML_SetElementHandler(svn_parser->parser, NULL, NULL); XML_SetCharacterDataHandler(svn_parser->parser, NULL); /* Once outside of XML_Parse(), the existence of this field will cause svn_delta_parse()'s main read-loop to return error. */ svn_parser->error = error;}/*** Attribute walking. ***/const char *svn_xml_get_attr_value(const char *name, const char **atts){ while (atts && (*atts)) { if (strcmp(atts[0], name) == 0) return atts[1]; else atts += 2; /* continue looping */ } /* Else no such attribute name seen. */ return NULL;}/*** Printing XML ***/voidsvn_xml_make_header(svn_stringbuf_t **str, apr_pool_t *pool){ if (*str == NULL) *str = svn_stringbuf_create("", pool); svn_stringbuf_appendcstr(*str, "<?xml version=\"1.0\"?>\n");}/*** Creating attribute hashes. ***//* Combine an existing attribute list ATTS with a HASH that itself represents an attribute list. Iff PRESERVE is true, then no value already in HASH will be changed, else values from ATTS will override previous values in HASH. */static voidamalgamate(const char **atts, apr_hash_t *ht, svn_boolean_t preserve, apr_pool_t *pool){ const char *key; if (atts) for (key = *atts; key; key = *(++atts)) { const char *val = *(++atts); size_t keylen; assert(key != NULL); /* kff todo: should we also insist that val be non-null here? Probably. */ keylen = strlen(key); if (preserve && ((apr_hash_get(ht, key, keylen)) != NULL)) continue; else apr_hash_set(ht, apr_pstrndup(pool, key, keylen), keylen, val ? apr_pstrdup(pool, val) : NULL); }}apr_hash_t *svn_xml_ap_to_hash(va_list ap, apr_pool_t *pool){ apr_hash_t *ht = apr_hash_make(pool); const char *key; while ((key = va_arg(ap, char *)) != NULL) { const char *val = va_arg(ap, const char *); apr_hash_set(ht, key, APR_HASH_KEY_STRING, val); } return ht;}apr_hash_t *svn_xml_make_att_hash(const char **atts, apr_pool_t *pool){ apr_hash_t *ht = apr_hash_make(pool); amalgamate(atts, ht, 0, pool); /* third arg irrelevant in this case */ return ht;}voidsvn_xml_hash_atts_overlaying(const char **atts, apr_hash_t *ht, apr_pool_t *pool){ amalgamate(atts, ht, 0, pool);}voidsvn_xml_hash_atts_preserving(const char **atts, apr_hash_t *ht, apr_pool_t *pool){ amalgamate(atts, ht, 1, pool);}/*** Making XML tags. ***/voidsvn_xml_make_open_tag_hash(svn_stringbuf_t **str, apr_pool_t *pool, enum svn_xml_open_tag_style style, const char *tagname, apr_hash_t *attributes){ apr_hash_index_t *hi; if (*str == NULL) *str = svn_stringbuf_create("", pool); svn_stringbuf_appendcstr(*str, "<"); svn_stringbuf_appendcstr(*str, tagname); for (hi = apr_hash_first(pool, attributes); hi; hi = apr_hash_next(hi)) { const void *key; void *val; apr_hash_this(hi, &key, NULL, &val); assert(val != NULL); svn_stringbuf_appendcstr(*str, "\n "); svn_stringbuf_appendcstr(*str, key); svn_stringbuf_appendcstr(*str, "=\""); svn_xml_escape_attr_cstring(str, val, pool); svn_stringbuf_appendcstr(*str, "\""); } if (style == svn_xml_self_closing) svn_stringbuf_appendcstr(*str, "/"); svn_stringbuf_appendcstr(*str, ">"); if (style != svn_xml_protect_pcdata) svn_stringbuf_appendcstr(*str, "\n");}voidsvn_xml_make_open_tag_v(svn_stringbuf_t **str, apr_pool_t *pool, enum svn_xml_open_tag_style style, const char *tagname, va_list ap){ apr_pool_t *subpool = svn_pool_create(pool); apr_hash_t *ht = svn_xml_ap_to_hash(ap, subpool); svn_xml_make_open_tag_hash(str, pool, style, tagname, ht); svn_pool_destroy(subpool);}voidsvn_xml_make_open_tag(svn_stringbuf_t **str, apr_pool_t *pool, enum svn_xml_open_tag_style style, const char *tagname, ...){ va_list ap; va_start(ap, tagname); svn_xml_make_open_tag_v(str, pool, style, tagname, ap); va_end(ap);}void svn_xml_make_close_tag(svn_stringbuf_t **str, apr_pool_t *pool, const char *tagname){ if (*str == NULL) *str = svn_stringbuf_create("", pool); svn_stringbuf_appendcstr(*str, "</"); svn_stringbuf_appendcstr(*str, tagname); svn_stringbuf_appendcstr(*str, ">\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -