Author: gstein
Date: Wed Jun 15 23:04:36 2011
New Revision: 1136241
URL: http://svn.apache.org/viewvc?rev=1136241&view=rev
Log:
Begin some rejiggering and cleaning of the XML parsing code in ra_serf.
Longer plan will enable "pausing" the parse loop in order to wait for
queued requests to be processed by the server.
* subversion/libsvn_ra_serf/util.c:
(add_done_item): make this function a bit more resilient against
multiple calls, to simplify callers and avoid horrible mistakes.
(inject_to_parser): new function to wrap the little bits where we inject
data into the parser, and check to see if the callbacks have raised
any errors. factored out of svn_ra_serf__handle_xml_parser()
(svn_ra_serf__handle_xml_parser): tighten scope of DATA and LEN vars.
use the new inject_to_parser() function. clear up some of the exit
conditions and wrap-up of data.
Modified:
subversion/trunk/subversion/libsvn_ra_serf/util.c
Modified: subversion/trunk/subversion/libsvn_ra_serf/util.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/util.c?rev=1136241&r1=1136240&r2=1136241&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/util.c Wed Jun 15 23:04:36 2011
@@ -1157,15 +1157,41 @@ cdata_xml(void *userData, const char *da
static void
add_done_item(svn_ra_serf__xml_parser_t *ctx)
{
- *ctx->done = TRUE;
- if (ctx->done_list)
+ /* Make sure we don't add to DONE_LIST twice. */
+ if (!*ctx->done)
{
- ctx->done_item->data = ctx->user_data;
- ctx->done_item->next = *ctx->done_list;
- *ctx->done_list = ctx->done_item;
+ *ctx->done = TRUE;
+ if (ctx->done_list)
+ {
+ ctx->done_item->data = ctx->user_data;
+ ctx->done_item->next = *ctx->done_list;
+ *ctx->done_list = ctx->done_item;
+ }
}
}
+
+static svn_error_t *
+inject_to_parser(svn_ra_serf__xml_parser_t *ctx,
+ const char *data,
+ apr_size_t len,
+ const serf_status_line *sl)
+{
+ int xml_status;
+
+ xml_status = XML_Parse(ctx->xmlp, data, len, 0);
+ if (xml_status == XML_STATUS_ERROR)
+ return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+ _("XML parsing failed: (%d %s)"),
+ sl->code, sl->reason);
+
+ if (ctx->error)
+ return svn_error_return(ctx->error);
+
+ return SVN_NO_ERROR;
+}
+
+
/* Implements svn_ra_serf__response_handler_t */
svn_error_t *
svn_ra_serf__handle_xml_parser(serf_request_t *request,
@@ -1173,11 +1199,8 @@ svn_ra_serf__handle_xml_parser(serf_requ
void *baton,
apr_pool_t *pool)
{
- const char *data;
- apr_size_t len;
serf_status_line sl;
apr_status_t status;
- int xml_status;
svn_ra_serf__xml_parser_t *ctx = baton;
svn_error_t *err;
@@ -1203,8 +1226,7 @@ svn_ra_serf__handle_xml_parser(serf_requ
/* If our caller won't know about the 404, abort() for now. */
SVN_ERR_ASSERT(ctx->status_code);
- if (*ctx->done == FALSE)
- add_done_item(ctx);
+ add_done_item(ctx);
err = svn_ra_serf__handle_server_error(request, response, pool);
@@ -1227,6 +1249,9 @@ svn_ra_serf__handle_xml_parser(serf_requ
while (1)
{
+ const char *data;
+ apr_size_t len;
+
status = serf_bucket_read(response, 8000, &data, &len);
if (SERF_BUCKET_READ_ERROR(status))
@@ -1234,25 +1259,17 @@ svn_ra_serf__handle_xml_parser(serf_requ
return svn_error_wrap_apr(status, NULL);
}
- xml_status = XML_Parse(ctx->xmlp, data, len, 0);
- if (xml_status == XML_STATUS_ERROR && ctx->ignore_errors == FALSE)
+ err = inject_to_parser(ctx, data, len, &sl);
+ if (err)
{
- XML_ParserFree(ctx->xmlp);
-
- SVN_ERR_ASSERT(ctx->status_code);
-
- if (*ctx->done == FALSE)
- add_done_item(ctx);
-
- return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
- _("XML parsing failed: (%d %s)"),
- sl.code, sl.reason);
- }
+ if (!ctx->ignore_errors)
+ {
+ XML_ParserFree(ctx->xmlp);
+ add_done_item(ctx);
+ return svn_error_return(err);
+ }
- if (ctx->error && ctx->ignore_errors == FALSE)
- {
- XML_ParserFree(ctx->xmlp);
- SVN_ERR(ctx->error);
+ svn_error_clear(err);
}
if (APR_STATUS_IS_EAGAIN(status))
@@ -1262,7 +1279,9 @@ svn_ra_serf__handle_xml_parser(serf_requ
if (APR_STATUS_IS_EOF(status))
{
- xml_status = XML_Parse(ctx->xmlp, NULL, 0, 1);
+ /* Ignore the return status. We just don't care. */
+ (void) XML_Parse(ctx->xmlp, NULL, 0, 1);
+
XML_ParserFree(ctx->xmlp);
add_done_item(ctx);
return svn_error_wrap_apr(status, NULL);