diff options
Diffstat (limited to 'subversion/libsvn_ra_serf/getdate.c')
-rw-r--r-- | subversion/libsvn_ra_serf/getdate.c | 156 |
1 files changed, 42 insertions, 114 deletions
diff --git a/subversion/libsvn_ra_serf/getdate.c b/subversion/libsvn_ra_serf/getdate.c index 3899ccf..cc1014e 100644 --- a/subversion/libsvn_ra_serf/getdate.c +++ b/subversion/libsvn_ra_serf/getdate.c @@ -24,9 +24,6 @@ #include <apr_uri.h> - -#include <expat.h> - #include <serf.h> #include "svn_pools.h" @@ -46,120 +43,54 @@ /* * This enum represents the current state of our XML parsing for a REPORT. */ -typedef enum date_state_e { - NONE = 0, +enum date_state_e { + INITIAL = 0, + REPORT, VERSION_NAME -} date_state_e; +}; -typedef struct date_info_t { - /* The currently collected value as we build it up */ - const char *tmp; - apr_size_t tmp_len; -} date_info_t; typedef struct date_context_t { - apr_pool_t *pool; - /* The time asked about. */ apr_time_t time; /* What was the youngest revision at that time? */ svn_revnum_t *revision; - /* are we done? */ - svn_boolean_t done; - } date_context_t; - -static date_info_t * -push_state(svn_ra_serf__xml_parser_t *parser, - date_context_t *date_ctx, - date_state_e state) -{ - svn_ra_serf__xml_push_state(parser, state); - - if (state == VERSION_NAME) - { - date_info_t *info; - - info = apr_pcalloc(parser->state->pool, sizeof(*info)); +#define D_ "DAV:" +#define S_ SVN_XML_NAMESPACE +static const svn_ra_serf__xml_transition_t date_ttable[] = { + { INITIAL, S_, "dated-rev-report", REPORT, + FALSE, { NULL }, FALSE }, - parser->state->private = info; - } + { REPORT, D_, SVN_DAV__VERSION_NAME, VERSION_NAME, + TRUE, { NULL }, TRUE }, - return parser->state->private; -} - -static svn_error_t * -start_getdate(svn_ra_serf__xml_parser_t *parser, - void *userData, - svn_ra_serf__dav_props_t name, - const char **attrs) -{ - date_context_t *date_ctx = userData; - date_state_e state; + { 0 } +}; - state = parser->state->current_state; - - if (state == NONE && - strcmp(name.name, SVN_DAV__VERSION_NAME) == 0) - { - push_state(parser, date_ctx, VERSION_NAME); - } - - return SVN_NO_ERROR; -} +/* Conforms to svn_ra_serf__xml_closed_t */ static svn_error_t * -end_getdate(svn_ra_serf__xml_parser_t *parser, - void *userData, - svn_ra_serf__dav_props_t name) +date_closed(svn_ra_serf__xml_estate_t *xes, + void *baton, + int leaving_state, + const svn_string_t *cdata, + apr_hash_t *attrs, + apr_pool_t *scratch_pool) { - date_context_t *date_ctx = userData; - date_state_e state; - date_info_t *info; + date_context_t *date_ctx = baton; - state = parser->state->current_state; - info = parser->state->private; + SVN_ERR_ASSERT(leaving_state == VERSION_NAME); + SVN_ERR_ASSERT(cdata != NULL); - if (state == VERSION_NAME && - strcmp(name.name, SVN_DAV__VERSION_NAME) == 0) - { - *date_ctx->revision = SVN_STR_TO_REV(info->tmp); - svn_ra_serf__xml_pop_state(parser); - } + *date_ctx->revision = SVN_STR_TO_REV(cdata->data); return SVN_NO_ERROR; } -static svn_error_t * -cdata_getdate(svn_ra_serf__xml_parser_t *parser, - void *userData, - const char *data, - apr_size_t len) -{ - date_context_t *date_ctx = userData; - date_state_e state; - date_info_t *info; - - UNUSED_CTX(date_ctx); - - state = parser->state->current_state; - info = parser->state->private; - - switch (state) - { - case VERSION_NAME: - svn_ra_serf__expand_string(&info->tmp, &info->tmp_len, - data, len, parser->state->pool); - break; - default: - break; - } - - return SVN_NO_ERROR; -} /* Implements svn_ra_serf__request_body_delegate_t */ static svn_error_t * @@ -198,19 +129,21 @@ svn_ra_serf__get_dated_revision(svn_ra_session_t *ra_session, date_context_t *date_ctx; svn_ra_serf__session_t *session = ra_session->priv; svn_ra_serf__handler_t *handler; - svn_ra_serf__xml_parser_t *parser_ctx; + svn_ra_serf__xml_context_t *xmlctx; const char *report_target; - int status_code; + svn_error_t *err; - date_ctx = apr_pcalloc(pool, sizeof(*date_ctx)); - date_ctx->pool = pool; + date_ctx = apr_palloc(pool, sizeof(*date_ctx)); date_ctx->time = tm; date_ctx->revision = revision; - date_ctx->done = FALSE; SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL, pool)); - handler = apr_pcalloc(pool, sizeof(*handler)); + xmlctx = svn_ra_serf__xml_context_create(date_ttable, + NULL, date_closed, NULL, + date_ctx, + pool); + handler = svn_ra_serf__create_expat_handler(xmlctx, pool); handler->method = "REPORT"; handler->path = report_target; @@ -218,25 +151,20 @@ svn_ra_serf__get_dated_revision(svn_ra_session_t *ra_session, handler->conn = session->conns[0]; handler->session = session; - parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx)); - - parser_ctx->pool = pool; - parser_ctx->user_data = date_ctx; - parser_ctx->start = start_getdate; - parser_ctx->end = end_getdate; - parser_ctx->cdata = cdata_getdate; - parser_ctx->done = &date_ctx->done; - parser_ctx->status_code = &status_code; - handler->body_delegate = create_getdate_body; handler->body_delegate_baton = date_ctx; - handler->response_handler = svn_ra_serf__handle_xml_parser; - handler->response_baton = parser_ctx; + *date_ctx->revision = SVN_INVALID_REVNUM; - svn_ra_serf__request_create(handler); + err = svn_ra_serf__context_run_one(handler, pool); - *date_ctx->revision = SVN_INVALID_REVNUM; + SVN_ERR(svn_error_compose_create( + svn_ra_serf__error_on_status(handler->sline, + report_target, + handler->location), + err)); + + SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(*revision)); - return svn_ra_serf__context_run_wait(&date_ctx->done, session, pool); + return SVN_NO_ERROR; } |