You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2012/05/14 16:07:47 UTC
svn commit: r1338209 [2/4] - in /subversion/branches/ev2-export: ./
build/ac-macros/ subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/include/ subversion/include/private/ subversion/libsvn_client/
subversion/libsvn_ra_serf/ subve...
Modified: subversion/branches/ev2-export/subversion/libsvn_client/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_client/util.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_client/util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_client/util.c Mon May 14 14:07:45 2012
@@ -232,6 +232,35 @@ svn_client__path_relative_to_root(const
}
svn_error_t *
+svn_client__wc_node_get_base(svn_client__pathrev_t **base_p,
+ const char *wc_abspath,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *relpath;
+
+ *base_p = apr_palloc(result_pool, sizeof(**base_p));
+
+ SVN_ERR(svn_wc__node_get_base(&(*base_p)->rev,
+ &relpath,
+ &(*base_p)->repos_root_url,
+ &(*base_p)->repos_uuid,
+ ctx->wc_ctx, wc_abspath,
+ result_pool, scratch_pool));
+ if ((*base_p)->repos_root_url && relpath)
+ {
+ (*base_p)->url = svn_path_url_add_component2(
+ (*base_p)->repos_root_url, relpath, result_pool);
+ }
+ else
+ {
+ *base_p = NULL;
+ }
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_client__wc_node_get_origin(svn_client__pathrev_t **origin_p,
const char *wc_abspath,
svn_client_ctx_t *ctx,
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/blame.c Mon May 14 14:07:45 2012
@@ -22,9 +22,6 @@
*/
#include <apr_uri.h>
-
-#include <expat.h>
-
#include <serf.h>
#include "svn_pools.h"
@@ -50,6 +47,7 @@
*/
typedef enum blame_state_e {
NONE = 0,
+ INITIAL = 0,
FILE_REVS_REPORT,
FILE_REV,
REV_PROP,
@@ -112,6 +110,42 @@ typedef struct blame_context_t {
void *file_rev_baton;
} blame_context_t;
+
+#if 0
+/* ### we cannot use this yet since the CDATA is unbounded and cannot be
+ ### collected by the parsing context. we need a streamy mechanism for
+ ### this report. */
+
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t blame_ttable[] = {
+ { INITIAL, S_, "file-revs-report", FILE_REVS_REPORT,
+ FALSE, { NULL }, FALSE, FALSE },
+
+ { FILE_REVS_REPORT, S_, "file-rev", FILE_REV,
+ FALSE, { "path", "rev", NULL }, FALSE, TRUE },
+
+ { FILE_REV, D_, "rev-prop", REV_PROP,
+ TRUE, { "name", "?encoding", NULL }, FALSE, TRUE },
+
+ { FILE_REV, D_, "set-prop", SET_PROP,
+ TRUE, { "name", "?encoding", NULL }, FALSE, TRUE },
+
+ { FILE_REV, D_, "remove-prop", REMOVE_PROP,
+ FALSE, { "name", "?encoding", NULL }, FALSE, TRUE },
+
+ { FILE_REV, D_, "merged-revision", MERGED_REVISION,
+ FALSE, { NULL }, FALSE, FALSE },
+
+ { FILE_REV, D_, "txdelta", TXDELTA,
+ TRUE, { NULL }, FALSE, TRUE },
+
+ { 0 }
+};
+
+#endif
+
+
static blame_info_t *
push_state(svn_ra_serf__xml_parser_t *parser,
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/commit.c Mon May 14 14:07:45 2012
@@ -22,9 +22,6 @@
*/
#include <apr_uri.h>
-
-#include <expat.h>
-
#include <serf.h>
#include "svn_pools.h"
@@ -1661,14 +1658,10 @@ add_directory(const char *path,
break;
case 403:
- if (handler->server_error)
- SVN_ERR(handler->server_error->error);
return svn_error_createf(SVN_ERR_RA_DAV_FORBIDDEN, NULL,
_("Access to '%s' forbidden"),
handler->path);
default:
- if (handler->server_error)
- SVN_ERR(handler->server_error->error);
return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
_("Adding directory failed: %s on %s "
"(%d %s)"),
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/get_deleted_rev.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/get_deleted_rev.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/get_deleted_rev.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/get_deleted_rev.c Mon May 14 14:07:45 2012
@@ -35,14 +35,13 @@
/*
* This enum represents the current state of our XML parsing for a REPORT.
*/
-typedef enum drev_state_e {
- NONE = 0,
+enum drev_state_e {
+ INITIAL = 0,
+ REPORT,
VERSION_NAME
-} drev_state_e;
+};
typedef struct drev_context_t {
- apr_pool_t *pool;
-
const char *path;
svn_revnum_t peg_revision;
svn_revnum_t end_revision;
@@ -51,91 +50,41 @@ typedef struct drev_context_t {
the range PEG_REVISION-END-END_REVISION? */
svn_revnum_t *revision_deleted;
- /* are we done? */
- svn_boolean_t done;
-
} drev_context_t;
-
-static void
-push_state(svn_ra_serf__xml_parser_t *parser,
- drev_context_t *drev_ctx,
- drev_state_e state)
-{
- svn_ra_serf__xml_push_state(parser, state);
-
- if (state == VERSION_NAME)
- parser->state->private = NULL;
-}
-
-static svn_error_t *
-start_getdrev(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- const char **attrs,
- apr_pool_t *scratch_pool)
-{
- drev_context_t *drev_ctx = parser->user_data;
- drev_state_e state;
-
- state = parser->state->current_state;
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t getdrev_ttable[] = {
+ { INITIAL, S_, "get-deleted-rev-report", REPORT,
+ FALSE, { NULL }, FALSE, FALSE },
- if (state == NONE &&
- strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
- {
- push_state(parser, drev_ctx, VERSION_NAME);
- }
+ { REPORT, D_, SVN_DAV__VERSION_NAME, VERSION_NAME,
+ TRUE, { NULL }, FALSE, TRUE },
- return SVN_NO_ERROR;
-}
-
-static svn_error_t *
-end_getdrev(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- apr_pool_t *scratch_pool)
-{
- drev_context_t *drev_ctx = parser->user_data;
- drev_state_e state;
- svn_string_t *info;
-
- state = parser->state->current_state;
- info = parser->state->private;
-
- if (state == VERSION_NAME &&
- strcmp(name.name, SVN_DAV__VERSION_NAME) == 0 &&
- info)
- {
- *drev_ctx->revision_deleted = SVN_STR_TO_REV(info->data);
- svn_ra_serf__xml_pop_state(parser);
- }
-
- return SVN_NO_ERROR;
-}
+ { 0 }
+};
+
+/* Conforms to svn_ra_serf__xml_closed_t */
static svn_error_t *
-cdata_getdrev(svn_ra_serf__xml_parser_t *parser,
- const char *data,
- apr_size_t len,
- apr_pool_t *scratch_pool)
+getdrev_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)
{
- drev_context_t *drev_ctx = parser->user_data;
- drev_state_e state;
+ drev_context_t *drev_ctx = baton;
- UNUSED_CTX(drev_ctx);
+ SVN_ERR_ASSERT(leaving_state == VERSION_NAME);
+ SVN_ERR_ASSERT(cdata != NULL);
- state = parser->state->current_state;
- switch (state)
- {
- case VERSION_NAME:
- parser->state->private = svn_string_ncreate(data, len,
- parser->state->pool);
- break;
- default:
- break;
- }
+ *drev_ctx->revision_deleted = SVN_STR_TO_REV(cdata->data);
return SVN_NO_ERROR;
}
+
/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_getdrev_body(serf_bucket_t **body_bkt,
@@ -186,7 +135,7 @@ svn_ra_serf__get_deleted_rev(svn_ra_sess
drev_context_t *drev_ctx;
svn_ra_serf__session_t *ras = 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 *req_url;
svn_error_t *err;
@@ -194,38 +143,27 @@ svn_ra_serf__get_deleted_rev(svn_ra_sess
drev_ctx->path = path;
drev_ctx->peg_revision = peg_revision;
drev_ctx->end_revision = end_revision;
- drev_ctx->pool = pool;
drev_ctx->revision_deleted = revision_deleted;
- drev_ctx->done = FALSE;
SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
ras, NULL /* conn */,
NULL /* url */, peg_revision,
pool, pool));
- parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
- parser_ctx->pool = pool;
- parser_ctx->user_data = drev_ctx;
- parser_ctx->start = start_getdrev;
- parser_ctx->end = end_getdrev;
- parser_ctx->cdata = cdata_getdrev;
- parser_ctx->done = &drev_ctx->done;
+ xmlctx = svn_ra_serf__xml_context_create(getdrev_ttable,
+ NULL, getdrev_closed, drev_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
- handler = apr_pcalloc(pool, sizeof(*handler));
- handler->handler_pool = pool;
handler->method = "REPORT";
handler->path = req_url;
handler->body_type = "text/xml";
- handler->response_handler = svn_ra_serf__handle_xml_parser;
handler->body_delegate = create_getdrev_body;
handler->body_delegate_baton = drev_ctx;
handler->conn = ras->conns[0];
handler->session = ras;
- handler->response_baton = parser_ctx;
- svn_ra_serf__request_create(handler);
-
- err = svn_ra_serf__context_run_wait(&drev_ctx->done, ras, pool);
+ err = svn_ra_serf__context_run_one(handler, pool);
/* Map status 501: Method Not Implemented to our not implemented error.
1.5.x servers and older don't support this report. */
@@ -234,5 +172,6 @@ svn_ra_serf__get_deleted_rev(svn_ra_sess
_("'%s' REPORT not implemented"),
"get-deleted-rev");
SVN_ERR(err);
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/getdate.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/getdate.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/getdate.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/getdate.c Mon May 14 14:07:45 2012
@@ -24,9 +24,6 @@
#include <apr_uri.h>
-
-#include <expat.h>
-
#include <serf.h>
#include "svn_pools.h"
@@ -46,10 +43,11 @@
/*
* 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_context_t {
@@ -59,79 +57,41 @@ typedef struct date_context_t {
/* What was the youngest revision at that time? */
svn_revnum_t *revision;
- /* are we done? */
- svn_boolean_t done;
-
} date_context_t;
+#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, FALSE },
-static svn_error_t *
-start_getdate(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- const char **attrs,
- apr_pool_t *scratch_pool)
-{
- date_context_t *date_ctx = parser->user_data;
- date_state_e state = parser->state->current_state;
-
- UNUSED_CTX(date_ctx);
-
- if (state == NONE &&
- strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
- {
- svn_ra_serf__xml_push_state(parser, VERSION_NAME);
+ { REPORT, D_, SVN_DAV__VERSION_NAME, VERSION_NAME,
+ TRUE, { NULL }, FALSE, TRUE },
- parser->state->private = svn_stringbuf_create_empty(parser->state->pool);
- }
+ { 0 }
+};
- 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,
- 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 = parser->user_data;
- date_state_e state = parser->state->current_state;
-
- if (state == VERSION_NAME &&
- strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
- {
- const svn_stringbuf_t *datebuf = parser->state->private;
-
- *date_ctx->revision = SVN_STR_TO_REV(datebuf->data);
- svn_ra_serf__xml_pop_state(parser);
- }
+ date_context_t *date_ctx = baton;
- return SVN_NO_ERROR;
-}
+ SVN_ERR_ASSERT(leaving_state == VERSION_NAME);
+ SVN_ERR_ASSERT(cdata != NULL);
-static svn_error_t *
-cdata_getdate(svn_ra_serf__xml_parser_t *parser,
- const char *data,
- apr_size_t len,
- apr_pool_t *scratch_pool)
-{
- date_context_t *date_ctx = parser->user_data;
- date_state_e state = parser->state->current_state;
- svn_stringbuf_t *datebuf;
-
- UNUSED_CTX(date_ctx);
-
- switch (state)
- {
- case VERSION_NAME:
- datebuf = parser->state->private;
- svn_stringbuf_appendbytes(datebuf, data, len);
- break;
- default:
- break;
- }
+ *date_ctx->revision = SVN_STR_TO_REV(cdata->data);
return SVN_NO_ERROR;
}
+
/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_getdate_body(serf_bucket_t **body_bkt,
@@ -169,45 +129,32 @@ svn_ra_serf__get_dated_revision(svn_ra_s
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;
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, date_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
- handler->handler_pool = pool;
handler->method = "REPORT";
handler->path = report_target;
handler->body_type = "text/xml";
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;
-
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;
-
- svn_ra_serf__request_create(handler);
-
*date_ctx->revision = SVN_INVALID_REVNUM;
/* ### use svn_ra_serf__error_on_status() ? */
- return svn_ra_serf__context_run_wait(&date_ctx->done, session, pool);
+ return svn_error_trace(svn_ra_serf__context_run_one(handler, pool));
}
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocations.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocations.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocations.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocations.c Mon May 14 14:07:45 2012
@@ -41,18 +41,11 @@
/*
* This enum represents the current state of our XML parsing for a REPORT.
*/
-typedef enum loc_state_e {
+enum loc_state_e {
+ INITIAL = 0,
REPORT,
LOCATION
-} loc_state_e;
-
-typedef struct loc_state_list_t {
- /* The current state that we are in now. */
- loc_state_e state;
-
- /* The previous state we were in. */
- struct loc_state_list_t *prev;
-} loc_state_list_t;
+};
typedef struct loc_context_t {
/* pool to allocate memory from */
@@ -66,112 +59,49 @@ typedef struct loc_context_t {
/* Returned location hash */
apr_hash_t *paths;
- /* Current state we're in */
- loc_state_list_t *state;
- loc_state_list_t *free_state;
-
- svn_boolean_t done;
} loc_context_t;
-
-static void
-push_state(loc_context_t *loc_ctx, loc_state_e state)
-{
- loc_state_list_t *new_state;
-
- if (!loc_ctx->free_state)
- {
- new_state = apr_palloc(loc_ctx->pool, sizeof(*loc_ctx->state));
- }
- else
- {
- new_state = loc_ctx->free_state;
- loc_ctx->free_state = loc_ctx->free_state->prev;
- }
- new_state->state = state;
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t getloc_ttable[] = {
+ { INITIAL, S_, "get-locations-report", REPORT,
+ FALSE, { NULL }, FALSE, FALSE },
- /* Add it to the state chain. */
- new_state->prev = loc_ctx->state;
- loc_ctx->state = new_state;
-}
+ { REPORT, S_, "location", LOCATION,
+ FALSE, { "?rev", "?path", NULL }, FALSE, TRUE },
-static void pop_state(loc_context_t *loc_ctx)
-{
- loc_state_list_t *free_state;
- free_state = loc_ctx->state;
- /* advance the current state */
- loc_ctx->state = loc_ctx->state->prev;
- free_state->prev = loc_ctx->free_state;
- loc_ctx->free_state = free_state;
-}
+ { 0 }
+};
+
+/* Conforms to svn_ra_serf__xml_closed_t */
static svn_error_t *
-start_getloc(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- const char **attrs,
- apr_pool_t *scratch_pool)
+getloc_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)
{
- loc_context_t *loc_ctx = parser->user_data;
+ loc_context_t *loc_ctx = baton;
+ const char *revstr;
+ const char *path;
- if (!loc_ctx->state && strcmp(name.name, "get-locations-report") == 0)
- {
- push_state(loc_ctx, REPORT);
- }
- else if (loc_ctx->state &&
- loc_ctx->state->state == REPORT &&
- strcmp(name.name, "location") == 0)
- {
- svn_revnum_t rev = SVN_INVALID_REVNUM;
- const char *revstr, *path;
+ SVN_ERR_ASSERT(leaving_state == LOCATION);
- revstr = svn_xml_get_attr_value("rev", attrs);
- if (revstr)
- {
- rev = SVN_STR_TO_REV(revstr);
- }
-
- path = svn_xml_get_attr_value("path", attrs);
-
- if (SVN_IS_VALID_REVNUM(rev) && path)
- {
- apr_hash_set(loc_ctx->paths,
- apr_pmemdup(loc_ctx->pool, &rev, sizeof(rev)),
- sizeof(rev),
- apr_pstrdup(loc_ctx->pool, path));
- }
+ revstr = apr_hash_get(attrs, "rev", APR_HASH_KEY_STRING);
+ path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING);
+ if (revstr != NULL && path != NULL)
+ {
+ svn_revnum_t rev = SVN_STR_TO_REV(revstr);
+ apr_hash_set(loc_ctx->paths,
+ apr_pmemdup(loc_ctx->pool, &rev, sizeof(rev)), sizeof(rev),
+ apr_pstrdup(loc_ctx->pool, path));
}
return SVN_NO_ERROR;
}
-static svn_error_t *
-end_getloc(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- apr_pool_t *scratch_pool)
-{
- loc_context_t *loc_ctx = parser->user_data;
- loc_state_list_t *cur_state;
-
- if (!loc_ctx->state)
- {
- return SVN_NO_ERROR;
- }
-
- cur_state = loc_ctx->state;
-
- if (cur_state->state == REPORT &&
- strcmp(name.name, "get-locations-report") == 0)
- {
- pop_state(loc_ctx);
- }
- else if (cur_state->state == LOCATION &&
- strcmp(name.name, "location") == 0)
- {
- pop_state(loc_ctx);
- }
-
- return SVN_NO_ERROR;
-}
/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
@@ -226,7 +156,7 @@ svn_ra_serf__get_locations(svn_ra_sessio
loc_context_t *loc_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 *req_url;
svn_error_t *err;
@@ -235,7 +165,6 @@ svn_ra_serf__get_locations(svn_ra_sessio
loc_ctx->path = path;
loc_ctx->peg_revision = peg_revision;
loc_ctx->location_revisions = location_revisions;
- loc_ctx->done = FALSE;
loc_ctx->paths = apr_hash_make(loc_ctx->pool);
*locations = loc_ctx->paths;
@@ -245,9 +174,11 @@ svn_ra_serf__get_locations(svn_ra_sessio
NULL /* url */, peg_revision,
pool, pool));
- handler = apr_pcalloc(pool, sizeof(*handler));
+ xmlctx = svn_ra_serf__xml_context_create(getloc_ttable,
+ NULL, getloc_closed, loc_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
- handler->handler_pool = pool;
handler->method = "REPORT";
handler->path = req_url;
handler->body_delegate = create_get_locations_body;
@@ -256,20 +187,7 @@ svn_ra_serf__get_locations(svn_ra_sessio
handler->conn = session->conns[0];
handler->session = session;
- parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
- parser_ctx->pool = pool;
- parser_ctx->user_data = loc_ctx;
- parser_ctx->start = start_getloc;
- parser_ctx->end = end_getloc;
- parser_ctx->done = &loc_ctx->done;
-
- handler->response_handler = svn_ra_serf__handle_xml_parser;
- handler->response_baton = parser_ctx;
-
- svn_ra_serf__request_create(handler);
-
- err = svn_ra_serf__context_run_wait(&loc_ctx->done, session, pool);
+ err = svn_ra_serf__context_run_one(handler, pool);
SVN_ERR(svn_error_compose_create(
svn_ra_serf__error_on_status(handler->sline.code,
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocationsegments.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocationsegments.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocationsegments.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocationsegments.c Mon May 14 14:07:45 2012
@@ -25,7 +25,6 @@
#include <apr_uri.h>
-#include <expat.h>
#include <serf.h>
#include "svn_pools.h"
@@ -50,80 +49,60 @@ typedef struct gls_context_t {
svn_location_segment_receiver_t receiver;
void *receiver_baton;
- /* subpool used only as long as a single receiver invocation */
- apr_pool_t *subpool;
-
- /* True iff we're looking at a child of the outer report tag */
- svn_boolean_t inside_report;
-
- svn_boolean_t done;
} gls_context_t;
+enum {
+ INITIAL = 0,
+ REPORT,
+ SEGMENT
+};
+
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t gls_ttable[] = {
+ { INITIAL, S_, "get-location-segments-report", REPORT,
+ FALSE, { NULL }, FALSE, FALSE },
-static svn_error_t *
-start_gls(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- const char **attrs,
- apr_pool_t *scratch_pool)
-{
- gls_context_t *gls_ctx = parser->user_data;
+ { REPORT, S_, "location-segment", SEGMENT,
+ FALSE, { "?path", "range-start", "range-end", NULL }, FALSE, TRUE },
- if ((! gls_ctx->inside_report)
- && strcmp(name.name, "get-location-segments-report") == 0)
- {
- gls_ctx->inside_report = TRUE;
- }
- else if (gls_ctx->inside_report
- && strcmp(name.name, "location-segment") == 0)
- {
- const char *rev_str;
- svn_revnum_t range_start = SVN_INVALID_REVNUM;
- svn_revnum_t range_end = SVN_INVALID_REVNUM;
- const char *path = NULL;
-
- path = svn_xml_get_attr_value("path", attrs);
- rev_str = svn_xml_get_attr_value("range-start", attrs);
- if (rev_str)
- range_start = SVN_STR_TO_REV(rev_str);
- rev_str = svn_xml_get_attr_value("range-end", attrs);
- if (rev_str)
- range_end = SVN_STR_TO_REV(rev_str);
-
- if (SVN_IS_VALID_REVNUM(range_start) && SVN_IS_VALID_REVNUM(range_end))
- {
- svn_location_segment_t *segment = apr_pcalloc(gls_ctx->subpool,
- sizeof(*segment));
- segment->path = path;
- segment->range_start = range_start;
- segment->range_end = range_end;
- SVN_ERR(gls_ctx->receiver(segment,
- gls_ctx->receiver_baton,
- gls_ctx->subpool));
- svn_pool_clear(gls_ctx->subpool);
- }
- else
- {
- return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
- _("Expected valid revision range"));
- }
- }
+ { 0 }
+};
- return SVN_NO_ERROR;
-}
+/* Conforms to svn_ra_serf__xml_closed_t */
static svn_error_t *
-end_gls(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- apr_pool_t *scratch_pool)
+gls_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)
{
- gls_context_t *gls_ctx = parser->user_data;
-
- if (strcmp(name.name, "get-location-segments-report") == 0)
- gls_ctx->inside_report = FALSE;
+ gls_context_t *gls_ctx = baton;
+ const char *path;
+ const char *start_str;
+ const char *end_str;
+ svn_location_segment_t segment;
+
+ SVN_ERR_ASSERT(leaving_state == SEGMENT);
+
+ path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING);
+ start_str = apr_hash_get(attrs, "range-start", APR_HASH_KEY_STRING);
+ end_str = apr_hash_get(attrs, "range-end", APR_HASH_KEY_STRING);
+
+ /* The transition table said these must exist. */
+ SVN_ERR_ASSERT(start_str && end_str);
+
+ segment.path = path; /* may be NULL */
+ segment.range_start = SVN_STR_TO_REV(start_str);
+ segment.range_end = SVN_STR_TO_REV(end_str);
+ SVN_ERR(gls_ctx->receiver(&segment, gls_ctx->receiver_baton, scratch_pool));
return SVN_NO_ERROR;
}
+
/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
create_gls_body(serf_bucket_t **body_bkt,
@@ -180,7 +159,7 @@ svn_ra_serf__get_location_segments(svn_r
gls_context_t *gls_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 *req_url;
svn_error_t *err;
@@ -191,18 +170,17 @@ svn_ra_serf__get_location_segments(svn_r
gls_ctx->end_rev = end_rev;
gls_ctx->receiver = receiver;
gls_ctx->receiver_baton = receiver_baton;
- gls_ctx->subpool = svn_pool_create(pool);
- gls_ctx->inside_report = FALSE;
- gls_ctx->done = FALSE;
SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
session, NULL /* conn */,
NULL /* url */, peg_revision,
pool, pool));
- handler = apr_pcalloc(pool, sizeof(*handler));
+ xmlctx = svn_ra_serf__xml_context_create(gls_ttable,
+ NULL, gls_closed, gls_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
- handler->handler_pool = pool;
handler->method = "REPORT";
handler->path = req_url;
handler->body_delegate = create_gls_body;
@@ -211,25 +189,7 @@ svn_ra_serf__get_location_segments(svn_r
handler->conn = session->conns[0];
handler->session = session;
- parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
- parser_ctx->pool = pool;
- parser_ctx->user_data = gls_ctx;
- parser_ctx->start = start_gls;
- parser_ctx->end = end_gls;
- parser_ctx->done = &gls_ctx->done;
-
- handler->response_handler = svn_ra_serf__handle_xml_parser;
- handler->response_baton = parser_ctx;
-
- svn_ra_serf__request_create(handler);
-
- err = svn_ra_serf__context_run_wait(&gls_ctx->done, session, pool);
-
- if (gls_ctx->inside_report)
- err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, err,
- _("Location segment report failed on '%s'@'%ld'"),
- path, peg_revision);
+ err = svn_ra_serf__context_run_one(handler, pool);
err = svn_error_compose_create(
svn_ra_serf__error_on_status(handler->sline.code,
@@ -237,8 +197,6 @@ svn_ra_serf__get_location_segments(svn_r
handler->location),
err);
- svn_pool_destroy(gls_ctx->subpool);
-
if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE))
return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, err, NULL);
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocks.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocks.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/getlocks.c Mon May 14 14:07:45 2012
@@ -46,8 +46,8 @@
/*
* This enum represents the current state of our XML parsing for a REPORT.
*/
-typedef enum lock_state_e {
- NONE = 0,
+enum {
+ INITIAL = 0,
REPORT,
LOCK,
PATH,
@@ -56,18 +56,7 @@ typedef enum lock_state_e {
COMMENT,
CREATION_DATE,
EXPIRATION_DATE
-} lock_state_e;
-
-typedef struct lock_info_t {
- /* Temporary pool */
- apr_pool_t *pool;
-
- svn_lock_t *lock;
-
- /* The currently collected value as we build it up */
- svn_stringbuf_t *cdata;
-
-} lock_info_t;
+};
typedef struct lock_context_t {
apr_pool_t *pool;
@@ -79,107 +68,55 @@ typedef struct lock_context_t {
/* return hash */
apr_hash_t *hash;
- /* are we done? */
- svn_boolean_t done;
-
} lock_context_t;
-
-static lock_info_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
- lock_context_t *lock_ctx,
- lock_state_e state)
-{
- svn_ra_serf__xml_push_state(parser, state);
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t getlocks_ttable[] = {
+ { INITIAL, S_, "get-locks-report", REPORT,
+ FALSE, { NULL }, FALSE, FALSE },
- if (state == LOCK)
- {
- lock_info_t *info;
+ { REPORT, S_, "lock", LOCK,
+ FALSE, { NULL }, FALSE, TRUE },
- info = apr_pcalloc(parser->state->pool, sizeof(*info));
+ { LOCK, S_, "path", PATH,
+ TRUE, { NULL }, FALSE, TRUE },
- info->pool = lock_ctx->pool;
- info->lock = svn_lock_create(lock_ctx->pool);
- info->cdata = svn_stringbuf_create_empty(info->pool);
+ { LOCK, S_, "token", TOKEN,
+ TRUE, { NULL }, FALSE, TRUE },
- parser->state->private = info;
- }
-
- return parser->state->private;
-}
+ { LOCK, S_, "owner", OWNER,
+ TRUE, { NULL }, FALSE, TRUE },
-static svn_error_t *
-start_getlocks(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- const char **attrs,
- apr_pool_t *scratch_pool)
-{
- lock_context_t *lock_ctx = parser->user_data;
- lock_state_e state;
+ { LOCK, S_, "comment", COMMENT,
+ TRUE, { NULL }, FALSE, TRUE },
- state = parser->state->current_state;
+ { LOCK, S_, SVN_DAV__CREATIONDATE, CREATION_DATE,
+ TRUE, { NULL }, FALSE, TRUE },
- if (state == NONE &&
- strcmp(name.name, "get-locks-report") == 0)
- {
- push_state(parser, lock_ctx, REPORT);
- }
- else if (state == REPORT &&
- strcmp(name.name, "lock") == 0)
- {
- push_state(parser, lock_ctx, LOCK);
- }
- else if (state == LOCK)
- {
- if (strcmp(name.name, "path") == 0)
- {
- push_state(parser, lock_ctx, PATH);
- }
- else if (strcmp(name.name, "token") == 0)
- {
- push_state(parser, lock_ctx, TOKEN);
- }
- else if (strcmp(name.name, "owner") == 0)
- {
- push_state(parser, lock_ctx, OWNER);
- }
- else if (strcmp(name.name, "comment") == 0)
- {
- push_state(parser, lock_ctx, COMMENT);
- }
- else if (strcmp(name.name, SVN_DAV__CREATIONDATE) == 0)
- {
- push_state(parser, lock_ctx, CREATION_DATE);
- }
- else if (strcmp(name.name, "expirationdate") == 0)
- {
- push_state(parser, lock_ctx, EXPIRATION_DATE);
- }
- }
+ { LOCK, S_, "expirationdate", EXPIRATION_DATE,
+ TRUE, { NULL }, FALSE, TRUE },
- return SVN_NO_ERROR;
-}
+ { 0 }
+};
+
+/* Conforms to svn_ra_serf__xml_closed_t */
static svn_error_t *
-end_getlocks(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- apr_pool_t *scratch_pool)
+getlocks_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)
{
- lock_context_t *lock_ctx = parser->user_data;
- lock_state_e state;
- lock_info_t *info;
-
- state = parser->state->current_state;
- info = parser->state->private;
+ lock_context_t *lock_ctx = baton;
- if (state == REPORT &&
- strcmp(name.name, "get-locks-report") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == LOCK &&
- strcmp(name.name, "lock") == 0)
+ if (leaving_state == LOCK)
{
+ const char *path = apr_hash_get(attrs, "path", APR_HASH_KEY_STRING);
+ svn_boolean_t save_lock = FALSE;
+
/* Filter out unwanted paths. Since Subversion only allows
locks on files, we can treat depth=immediates the same as
depth=files for filtering purposes. Meaning, we'll keep
@@ -190,108 +127,81 @@ end_getlocks(svn_ra_serf__xml_parser_t *
c) we've asked for depth=files or depth=immediates, and this
lock is on an immediate child of our query path.
*/
- if ((strcmp(lock_ctx->path, info->lock->path) == 0)
- || (lock_ctx->requested_depth == svn_depth_infinity))
+ if (strcmp(lock_ctx->path, path) == 0
+ || lock_ctx->requested_depth == svn_depth_infinity)
{
- apr_hash_set(lock_ctx->hash, info->lock->path,
- APR_HASH_KEY_STRING, info->lock);
+ save_lock = TRUE;
}
- else if ((lock_ctx->requested_depth == svn_depth_files) ||
- (lock_ctx->requested_depth == svn_depth_immediates))
+ else if (lock_ctx->requested_depth == svn_depth_files
+ || lock_ctx->requested_depth == svn_depth_immediates)
{
- const char *rel_path = svn_fspath__skip_ancestor(lock_ctx->path,
- info->lock->path);
- if (rel_path && (svn_path_component_count(rel_path) == 1))
- apr_hash_set(lock_ctx->hash, info->lock->path,
- APR_HASH_KEY_STRING, info->lock);
- }
+ const char *relpath = svn_fspath__skip_ancestor(lock_ctx->path,
+ path);
+ if (relpath && (svn_path_component_count(relpath) == 1))
+ save_lock = TRUE;
+ }
+
+ if (save_lock)
+ {
+ /* We get to put the structure on the stack rather than using
+ svn_lock_create(). Bwahahaha.... */
+ svn_lock_t lock = { 0 };
+ const char *date;
+ svn_lock_t *result_lock;
+
+ /* Note: these "attributes" came from child elements. Some of
+ them may have not been sent, so the value will be NULL. */
+
+ lock.path = path;
+ lock.token = apr_hash_get(attrs, "token", APR_HASH_KEY_STRING);
+ lock.owner = apr_hash_get(attrs, "owner", APR_HASH_KEY_STRING);
+ lock.comment = apr_hash_get(attrs, "comment", APR_HASH_KEY_STRING);
+
+ date = apr_hash_get(attrs, SVN_DAV__CREATIONDATE,
+ APR_HASH_KEY_STRING);
+ if (date)
+ SVN_ERR(svn_time_from_cstring(&lock.creation_date, date,
+ scratch_pool));
+
+ date = apr_hash_get(attrs, "expirationdate",
+ APR_HASH_KEY_STRING);
+ if (date)
+ SVN_ERR(svn_time_from_cstring(&lock.expiration_date, date,
+ scratch_pool));
+
+ result_lock = svn_lock_dup(&lock, lock_ctx->pool);
+ apr_hash_set(lock_ctx->hash, result_lock->path, APR_HASH_KEY_STRING,
+ result_lock);
+ }
+ }
+ else
+ {
+ const char *name;
+
+ SVN_ERR_ASSERT(cdata != NULL);
+
+ if (leaving_state == PATH)
+ name = "path";
+ else if (leaving_state == TOKEN)
+ name = "token";
+ else if (leaving_state == OWNER)
+ name = "owner";
+ else if (leaving_state == COMMENT)
+ name = "comment";
+ else if (leaving_state == CREATION_DATE)
+ name = SVN_DAV__CREATIONDATE;
+ else if (leaving_state == EXPIRATION_DATE)
+ name = "expirationdate";
+ else
+ SVN_ERR_MALFUNCTION();
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == PATH &&
- strcmp(name.name, "path") == 0)
- {
- info->lock->path = apr_pstrmemdup(info->pool,
- info->cdata->data, info->cdata->len);
- svn_stringbuf_setempty(info->cdata);
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == TOKEN &&
- strcmp(name.name, "token") == 0)
- {
- info->lock->token = apr_pstrmemdup(info->pool,
- info->cdata->data, info->cdata->len);
- svn_stringbuf_setempty(info->cdata);
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == OWNER &&
- strcmp(name.name, "owner") == 0)
- {
- info->lock->owner = apr_pstrmemdup(info->pool,
- info->cdata->data, info->cdata->len);
- svn_stringbuf_setempty(info->cdata);
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == COMMENT &&
- strcmp(name.name, "comment") == 0)
- {
- info->lock->comment = apr_pstrmemdup(info->pool,
- info->cdata->data,
- info->cdata->len);
- svn_stringbuf_setempty(info->cdata);
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == CREATION_DATE &&
- strcmp(name.name, SVN_DAV__CREATIONDATE) == 0)
- {
- SVN_ERR(svn_time_from_cstring(&info->lock->creation_date,
- info->cdata->data, info->pool));
- svn_stringbuf_setempty(info->cdata);
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == EXPIRATION_DATE &&
- strcmp(name.name, "expirationdate") == 0)
- {
- SVN_ERR(svn_time_from_cstring(&info->lock->expiration_date,
- info->cdata->data, info->pool));
- svn_stringbuf_setempty(info->cdata);
- svn_ra_serf__xml_pop_state(parser);
+ /* Store the lock information onto the LOCK elemstate. */
+ svn_ra_serf__xml_note(xes, LOCK, name, cdata->data);
}
return SVN_NO_ERROR;
}
-static svn_error_t *
-cdata_getlocks(svn_ra_serf__xml_parser_t *parser,
- const char *data,
- apr_size_t len,
- apr_pool_t *scratch_pool)
-{
- lock_context_t *lock_ctx = parser->user_data;
- lock_state_e state;
- lock_info_t *info;
-
- UNUSED_CTX(lock_ctx);
-
- state = parser->state->current_state;
- info = parser->state->private;
-
- switch (state)
- {
- case PATH:
- case TOKEN:
- case OWNER:
- case COMMENT:
- case CREATION_DATE:
- case EXPIRATION_DATE:
- svn_stringbuf_appendbytes(info->cdata, data, len);
- break;
- default:
- break;
- }
-
- return SVN_NO_ERROR;
-}
/* Implements svn_ra_serf__request_body_delegate_t */
static svn_error_t *
@@ -324,7 +234,7 @@ svn_ra_serf__get_locks(svn_ra_session_t
lock_context_t *lock_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 *req_url, *rel_path;
req_url = svn_path_url_add_component2(session->session_url.path, path, pool);
@@ -336,37 +246,24 @@ svn_ra_serf__get_locks(svn_ra_session_t
lock_ctx->path = apr_pstrcat(pool, "/", rel_path, (char *)NULL);
lock_ctx->requested_depth = depth;
lock_ctx->hash = apr_hash_make(pool);
- lock_ctx->done = FALSE;
- handler = apr_pcalloc(pool, sizeof(*handler));
+ xmlctx = svn_ra_serf__xml_context_create(getlocks_ttable,
+ NULL, getlocks_closed, lock_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
- handler->handler_pool = pool;
handler->method = "REPORT";
handler->path = req_url;
handler->body_type = "text/xml";
handler->conn = session->conns[0];
handler->session = session;
- parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
- parser_ctx->pool = pool;
- parser_ctx->user_data = lock_ctx;
- parser_ctx->start = start_getlocks;
- parser_ctx->end = end_getlocks;
- parser_ctx->cdata = cdata_getlocks;
- parser_ctx->done = &lock_ctx->done;
-
handler->body_delegate = create_getlocks_body;
handler->body_delegate_baton = lock_ctx;
- handler->response_handler = svn_ra_serf__handle_xml_parser;
- handler->response_baton = parser_ctx;
-
- svn_ra_serf__request_create(handler);
-
/* ### use svn_ra_serf__error_on_status() ? */
- SVN_ERR(svn_ra_serf__context_run_wait(&lock_ctx->done, session, pool));
+ SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
*locks = lock_ctx->hash;
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/locks.c Mon May 14 14:07:45 2012
@@ -24,9 +24,6 @@
#include <apr_uri.h>
-
-#include <expat.h>
-
#include <serf.h>
#include "svn_dav.h"
@@ -45,8 +42,11 @@
/*
* This enum represents the current state of our XML parsing for a REPORT.
*/
-typedef enum lock_state_e {
- NONE = 0,
+enum {
+ INITIAL = 0,
+ MULTISTATUS,
+ RESPONSE,
+ PROPSTAT,
PROP,
LOCK_DISCOVERY,
ACTIVE_LOCK,
@@ -55,8 +55,9 @@ typedef enum lock_state_e {
DEPTH,
TIMEOUT,
LOCK_TOKEN,
- COMMENT
-} lock_state_e;
+ OWNER,
+ HREF
+};
typedef struct lock_info_t {
apr_pool_t *pool;
@@ -72,240 +73,117 @@ typedef struct lock_info_t {
svn_ra_serf__handler_t *handler;
+ /* The expat handler. We wrap this to do a bit more work. */
+ svn_ra_serf__response_handler_t inner_handler;
+ void *inner_baton;
+
} lock_info_t;
-
-static svn_stringbuf_t *
-push_state(svn_ra_serf__xml_parser_t *parser,
- lock_info_t *lock_ctx,
- lock_state_e state)
-{
- svn_ra_serf__xml_push_state(parser, state);
- switch (state)
- {
- case LOCK_TYPE:
- case LOCK_SCOPE:
- case DEPTH:
- case TIMEOUT:
- case LOCK_TOKEN:
- case COMMENT:
- parser->state->private =
- svn_stringbuf_create_empty(parser->state->pool);
- break;
- default:
- break;
- }
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t locks_ttable[] = {
+ /* The INITIAL state can transition into D:prop (LOCK) or
+ to D:multistatus (PROPFIND) */
+ { INITIAL, D_, "prop", PROP,
+ FALSE, { NULL }, FALSE, FALSE },
+ { INITIAL, D_, "multistatus", MULTISTATUS,
+ FALSE, { NULL }, FALSE, FALSE },
- return parser->state->private;
-}
+ { MULTISTATUS, D_, "response", RESPONSE,
+ FALSE, { NULL }, FALSE, FALSE },
-/*
- * Expat callback invoked on a start element tag for a PROPFIND response.
- */
-static svn_error_t *
-start_lock(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- const char **attrs,
- apr_pool_t *scratch_pool)
-{
- lock_info_t *ctx = parser->user_data;
- lock_state_e state;
+ { RESPONSE, D_, "propstat", PROPSTAT,
+ FALSE, { NULL }, FALSE, FALSE },
- state = parser->state->current_state;
+ { PROPSTAT, D_, "prop", PROP,
+ FALSE, { NULL }, FALSE, FALSE },
- if (state == NONE && strcmp(name.name, "prop") == 0)
- {
- svn_ra_serf__xml_push_state(parser, PROP);
- }
- else if (state == PROP &&
- strcmp(name.name, "lockdiscovery") == 0)
- {
- push_state(parser, ctx, LOCK_DISCOVERY);
- }
- else if (state == LOCK_DISCOVERY &&
- strcmp(name.name, "activelock") == 0)
- {
- push_state(parser, ctx, ACTIVE_LOCK);
- }
- else if (state == ACTIVE_LOCK)
- {
- if (strcmp(name.name, "locktype") == 0)
- {
- push_state(parser, ctx, LOCK_TYPE);
- }
- else if (strcmp(name.name, "lockscope") == 0)
- {
- push_state(parser, ctx, LOCK_SCOPE);
- }
- else if (strcmp(name.name, "depth") == 0)
- {
- push_state(parser, ctx, DEPTH);
- }
- else if (strcmp(name.name, "timeout") == 0)
- {
- push_state(parser, ctx, TIMEOUT);
- }
- else if (strcmp(name.name, "locktoken") == 0)
- {
- push_state(parser, ctx, LOCK_TOKEN);
- }
- else if (strcmp(name.name, "owner") == 0)
- {
- push_state(parser, ctx, COMMENT);
- }
- }
- else if (state == LOCK_TYPE)
- {
- if (strcmp(name.name, "write") == 0)
- {
- /* Do nothing. */
- }
- else
- {
- SVN_ERR_MALFUNCTION();
- }
- }
- else if (state == LOCK_SCOPE)
- {
- if (strcmp(name.name, "exclusive") == 0)
- {
- /* Do nothing. */
- }
- else
- {
- SVN_ERR_MALFUNCTION();
- }
- }
+ { PROP, D_, "lockdiscovery", LOCK_DISCOVERY,
+ FALSE, { NULL }, FALSE, FALSE },
- return SVN_NO_ERROR;
-}
+ { LOCK_DISCOVERY, D_, "activelock", ACTIVE_LOCK,
+ FALSE, { NULL }, FALSE, FALSE },
-/*
- * Expat callback invoked on an end element tag for a PROPFIND response.
- */
+#if 0
+ /* ### we don't really need to parse locktype/lockscope. we know what
+ ### the values are going to be. we *could* validate that the only
+ ### possible children are D:write and D:exclusive. we'd need to
+ ### modify the state transition to tell us about all children
+ ### (ie. maybe support "*" for the name) and then validate. but it
+ ### just isn't important to validate, so disable this for now... */
+
+ { ACTIVE_LOCK, D_, "locktype", LOCK_TYPE,
+ FALSE, { NULL }, FALSE, FALSE },
+
+ { LOCK_TYPE, D_, "write", WRITE,
+ FALSE, { NULL }, FALSE, TRUE },
+
+ { ACTIVE_LOCK, D_, "lockscope", LOCK_SCOPE,
+ FALSE, { NULL }, FALSE, FALSE },
+
+ { LOCK_SCOPE, D_, "exclusive", EXCLUSIVE,
+ FALSE, { NULL }, FALSE, TRUE },
+#endif /* 0 */
+
+ { ACTIVE_LOCK, D_, "timeout", TIMEOUT,
+ TRUE, { NULL }, FALSE, TRUE },
+
+ { ACTIVE_LOCK, D_, "locktoken", LOCK_TOKEN,
+ FALSE, { NULL }, FALSE, FALSE },
+
+ { LOCK_TOKEN, D_, "href", HREF,
+ TRUE, { NULL }, FALSE, TRUE },
+
+ { ACTIVE_LOCK, D_, "owner", OWNER,
+ TRUE, { NULL }, FALSE, TRUE },
+
+ /* ACTIVE_LOCK has a D:depth child, but we can ignore that. */
+
+ { 0 }
+};
+
+
+/* Conforms to svn_ra_serf__xml_closed_t */
static svn_error_t *
-end_lock(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- apr_pool_t *scratch_pool)
+locks_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)
{
- lock_info_t *ctx = parser->user_data;
- lock_state_e state;
-
- state = parser->state->current_state;
+ lock_info_t *lock_ctx = baton;
- if (state == PROP &&
- strcmp(name.name, "prop") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == LOCK_DISCOVERY &&
- strcmp(name.name, "lockdiscovery") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == ACTIVE_LOCK &&
- strcmp(name.name, "activelock") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == LOCK_TYPE &&
- strcmp(name.name, "locktype") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == LOCK_SCOPE &&
- strcmp(name.name, "lockscope") == 0)
+ if (leaving_state == TIMEOUT)
{
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == DEPTH &&
- strcmp(name.name, "depth") == 0)
- {
- svn_ra_serf__xml_pop_state(parser);
- }
- else if (state == TIMEOUT &&
- strcmp(name.name, "timeout") == 0)
- {
- svn_stringbuf_t *info = parser->state->private;
-
- if (strcmp(info->data, "Infinite") == 0)
- {
- ctx->lock->expiration_date = 0;
- }
+ if (strcmp(cdata->data, "Infinite") == 0)
+ lock_ctx->lock->expiration_date = 0;
else
- {
- SVN_ERR(svn_time_from_cstring(&ctx->lock->creation_date,
- info->data, ctx->pool));
- }
- svn_ra_serf__xml_pop_state(parser);
+ SVN_ERR(svn_time_from_cstring(&lock_ctx->lock->creation_date,
+ cdata->data, lock_ctx->pool));
}
- else if (state == LOCK_TOKEN &&
- strcmp(name.name, "locktoken") == 0)
+ else if (leaving_state == HREF)
{
- svn_stringbuf_t *info = parser->state->private;
-
- if (!ctx->lock->token && info->len)
+ if (cdata->len)
{
- apr_collapse_spaces(info->data, info->data);
- ctx->lock->token = apr_pstrmemdup(ctx->pool, info->data, info->len);
+ char *buf = apr_pstrmemdup(lock_ctx->pool, cdata->data, cdata->len);
+
+ apr_collapse_spaces(buf, buf);
+ lock_ctx->lock->token = buf;
}
- /* We don't actually need the lock token. */
- svn_ra_serf__xml_pop_state(parser);
}
- else if (state == COMMENT &&
- strcmp(name.name, "owner") == 0)
+ else if (leaving_state == OWNER)
{
- svn_stringbuf_t *info = parser->state->private;
-
- if (info->len)
+ if (cdata->len)
{
- ctx->lock->comment = apr_pstrmemdup(ctx->pool,
- info->data, info->len);
+ lock_ctx->lock->comment = apr_pstrmemdup(lock_ctx->pool,
+ cdata->data, cdata->len);
}
- svn_ra_serf__xml_pop_state(parser);
}
return SVN_NO_ERROR;
}
-static svn_error_t *
-cdata_lock(svn_ra_serf__xml_parser_t *parser,
- const char *data,
- apr_size_t len,
- apr_pool_t *scratch_pool)
-{
- lock_info_t *lock_ctx = parser->user_data;
- lock_state_e state;
- svn_stringbuf_t *info;
-
- UNUSED_CTX(lock_ctx);
-
- state = parser->state->current_state;
- info = parser->state->private;
-
- switch (state)
- {
- case LOCK_TYPE:
- case LOCK_SCOPE:
- case DEPTH:
- case TIMEOUT:
- case LOCK_TOKEN:
- case COMMENT:
- svn_stringbuf_appendbytes(info, data, len);
- break;
-
- default:
- break;
- }
-
- return SVN_NO_ERROR;
-}
-
-static const svn_ra_serf__dav_props_t lock_props[] =
-{
- { "DAV:", "lockdiscovery" },
- { NULL }
-};
static svn_error_t *
set_lock_headers(serf_bucket_t *headers,
@@ -336,13 +214,6 @@ static svn_error_t *
determine_error(svn_ra_serf__handler_t *handler,
svn_error_t *err)
{
- /* If we found an error in the response, then blend it in. */
- if (handler->server_error)
- {
- /* Client-side error takes precedence. */
- err = svn_error_compose_create(err, handler->server_error->error);
- }
- else
{
apr_status_t errcode;
@@ -353,9 +224,13 @@ determine_error(svn_ra_serf__handler_t *
else
return err;
+ /* Client-side or server-side error already. Return it. */
+ if (err != NULL)
+ return err;
+
/* The server did not send us a detailed human-readable error.
Provide a generic error. */
- err = svn_error_createf(errcode, err,
+ err = svn_error_createf(errcode, NULL,
_("Lock request failed: %d %s"),
handler->sline.code,
handler->sline.reason);
@@ -372,8 +247,7 @@ handle_lock(serf_request_t *request,
void *handler_baton,
apr_pool_t *pool)
{
- svn_ra_serf__xml_parser_t *xml_ctx = handler_baton;
- lock_info_t *ctx = xml_ctx->user_data;
+ lock_info_t *ctx = handler_baton;
/* 403 (Forbidden) when a lock doesn't exist.
423 (Locked) when a lock already exists. */
@@ -410,8 +284,7 @@ handle_lock(serf_request_t *request,
ctx->read_headers = TRUE;
}
- return svn_ra_serf__handle_xml_parser(request, response,
- handler_baton, pool);
+ return ctx->inner_handler(request, response, ctx->inner_baton, pool);
}
/* Implements svn_ra_serf__request_body_delegate_t */
@@ -443,7 +316,7 @@ setup_getlock_headers(serf_bucket_t *hea
void *baton,
apr_pool_t *pool)
{
- serf_bucket_headers_set(headers, "Depth", "0");
+ serf_bucket_headers_setn(headers, "Depth", "0");
return SVN_NO_ERROR;
}
@@ -493,7 +366,7 @@ svn_ra_serf__get_lock(svn_ra_session_t *
{
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;
lock_info_t *lock_ctx;
const char *req_url;
svn_error_t *err;
@@ -505,34 +378,29 @@ svn_ra_serf__get_lock(svn_ra_session_t *
lock_ctx->pool = pool;
lock_ctx->path = req_url;
lock_ctx->lock = svn_lock_create(pool);
- lock_ctx->lock->path = path;
+ lock_ctx->lock->path = apr_pstrdup(pool, path); /* be sure */
- handler = apr_pcalloc(pool, sizeof(*handler));
+ xmlctx = svn_ra_serf__xml_context_create(locks_ttable,
+ NULL, locks_closed, lock_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
- handler->handler_pool = pool;
handler->method = "PROPFIND";
handler->path = req_url;
handler->body_type = "text/xml";
handler->conn = session->conns[0];
handler->session = session;
- parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
- parser_ctx->pool = pool;
- parser_ctx->user_data = lock_ctx;
- parser_ctx->start = start_lock;
- parser_ctx->end = end_lock;
- parser_ctx->cdata = cdata_lock;
- parser_ctx->done = &handler->done;
-
handler->body_delegate = create_getlock_body;
handler->body_delegate_baton = lock_ctx;
handler->header_delegate = setup_getlock_headers;
handler->header_delegate_baton = lock_ctx;
+ lock_ctx->inner_handler = handler->response_handler;
+ lock_ctx->inner_baton = handler->response_baton;
handler->response_handler = handle_lock;
- handler->response_baton = parser_ctx;
+ handler->response_baton = lock_ctx;
lock_ctx->handler = handler;
@@ -581,7 +449,7 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
hi = apr_hash_next(hi))
{
svn_ra_serf__handler_t *handler;
- svn_ra_serf__xml_parser_t *parser_ctx;
+ svn_ra_serf__xml_context_t *xmlctx;
const char *req_url;
lock_info_t *lock_ctx;
svn_error_t *err;
@@ -602,32 +470,27 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
req_url = svn_path_url_add_component2(session->session_url.path,
lock_ctx->path, iterpool);
- handler = apr_pcalloc(iterpool, sizeof(*handler));
+ xmlctx = svn_ra_serf__xml_context_create(locks_ttable,
+ NULL, locks_closed, lock_ctx,
+ iterpool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, iterpool);
- handler->handler_pool = iterpool;
handler->method = "LOCK";
handler->path = req_url;
handler->body_type = "text/xml";
handler->conn = session->conns[0];
handler->session = session;
- parser_ctx = apr_pcalloc(iterpool, sizeof(*parser_ctx));
-
- parser_ctx->pool = iterpool;
- parser_ctx->user_data = lock_ctx;
- parser_ctx->start = start_lock;
- parser_ctx->end = end_lock;
- parser_ctx->cdata = cdata_lock;
- parser_ctx->done = &handler->done;
-
handler->header_delegate = set_lock_headers;
handler->header_delegate_baton = lock_ctx;
handler->body_delegate = create_lock_body;
handler->body_delegate_baton = lock_ctx;
+ lock_ctx->inner_handler = handler->response_handler;
+ lock_ctx->inner_baton = handler->response_baton;
handler->response_handler = handle_lock;
- handler->response_baton = parser_ctx;
+ handler->response_baton = lock_ctx;
lock_ctx->handler = handler;
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/log.c Mon May 14 14:07:45 2012
@@ -24,9 +24,6 @@
#include <apr_uri.h>
-
-#include <expat.h>
-
#include <serf.h>
#include "svn_pools.h"
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/options.c Mon May 14 14:07:45 2012
@@ -48,162 +48,68 @@
/*
* This enum represents the current state of our XML parsing for an OPTIONS.
*/
-typedef enum options_state_e {
+enum options_state_e {
+ INITIAL = 0,
OPTIONS,
ACTIVITY_COLLECTION,
HREF
-} options_state_e;
-
-typedef struct options_state_list_t {
- /* The current state that we are in now. */
- options_state_e state;
-
- /* The previous state we were in. */
- struct options_state_list_t *prev;
-} options_state_list_t;
+};
typedef struct options_context_t {
/* pool to allocate memory from */
apr_pool_t *pool;
- /* Buffer for the activity-collection */
- svn_stringbuf_t *acbuf;
- svn_boolean_t collect_cdata;
-
- /* Current state we're in */
- options_state_list_t *state;
- options_state_list_t *free_state;
-
/* Have we extracted options values from the headers already? */
svn_boolean_t headers_processed;
- /* are we done? */
- svn_boolean_t done;
-
svn_ra_serf__session_t *session;
svn_ra_serf__connection_t *conn;
svn_ra_serf__handler_t *handler;
- svn_ra_serf__xml_parser_t *parser_ctx;
+
+ svn_ra_serf__response_handler_t inner_handler;
+ void *inner_baton;
const char *activity_collection;
svn_revnum_t youngest_rev;
} options_context_t;
+#define D_ "DAV:"
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t options_ttable[] = {
+ { INITIAL, D_, "options-response", OPTIONS,
+ FALSE, { NULL }, FALSE, FALSE },
-static void
-push_state(options_context_t *options_ctx, options_state_e state)
-{
- options_state_list_t *new_state;
-
- if (!options_ctx->free_state)
- {
- new_state = apr_palloc(options_ctx->pool, sizeof(*options_ctx->state));
- }
- else
- {
- new_state = options_ctx->free_state;
- options_ctx->free_state = options_ctx->free_state->prev;
- }
- new_state->state = state;
+ { OPTIONS, D_, "activity-collection-set", ACTIVITY_COLLECTION,
+ FALSE, { NULL }, FALSE, FALSE },
- /* Add it to the state chain. */
- new_state->prev = options_ctx->state;
- options_ctx->state = new_state;
-}
+ { ACTIVITY_COLLECTION, D_, "href", HREF,
+ TRUE, { NULL }, FALSE, TRUE },
-static void pop_state(options_context_t *options_ctx)
-{
- options_state_list_t *free_state;
- free_state = options_ctx->state;
- /* advance the current state */
- options_ctx->state = options_ctx->state->prev;
- free_state->prev = options_ctx->free_state;
- options_ctx->free_state = free_state;
-}
+ { 0 }
+};
-static svn_error_t *
-start_options(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- const char **attrs,
- apr_pool_t *scratch_pool)
-{
- options_context_t *options_ctx = parser->user_data;
-
- if (!options_ctx->state && strcmp(name.name, "options-response") == 0)
- {
- push_state(options_ctx, OPTIONS);
- }
- else if (!options_ctx->state)
- {
- /* Nothing to do. */
- return SVN_NO_ERROR;
- }
- else if (options_ctx->state->state == OPTIONS &&
- strcmp(name.name, "activity-collection-set") == 0)
- {
- push_state(options_ctx, ACTIVITY_COLLECTION);
- }
- else if (options_ctx->state->state == ACTIVITY_COLLECTION &&
- strcmp(name.name, "href") == 0)
- {
- options_ctx->collect_cdata = TRUE;
- push_state(options_ctx, HREF);
- }
-
- return SVN_NO_ERROR;
-}
+/* Conforms to svn_ra_serf__xml_closed_t */
static svn_error_t *
-end_options(svn_ra_serf__xml_parser_t *parser,
- svn_ra_serf__dav_props_t name,
- apr_pool_t *scratch_pool)
+options_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)
{
- options_context_t *options_ctx = parser->user_data;
- options_state_list_t *cur_state;
-
- if (!options_ctx->state)
- {
- return SVN_NO_ERROR;
- }
+ options_context_t *opt_ctx = baton;
- cur_state = options_ctx->state;
+ SVN_ERR_ASSERT(leaving_state == HREF);
+ SVN_ERR_ASSERT(cdata != NULL);
- if (cur_state->state == OPTIONS &&
- strcmp(name.name, "options-response") == 0)
- {
- pop_state(options_ctx);
- }
- else if (cur_state->state == ACTIVITY_COLLECTION &&
- strcmp(name.name, "activity-collection-set") == 0)
- {
- pop_state(options_ctx);
- }
- else if (cur_state->state == HREF &&
- strcmp(name.name, "href") == 0)
- {
- options_ctx->collect_cdata = FALSE;
- options_ctx->activity_collection =
- svn_urlpath__canonicalize(options_ctx->acbuf->data, options_ctx->pool);
- pop_state(options_ctx);
- }
+ opt_ctx->activity_collection = svn_urlpath__canonicalize(cdata->data,
+ opt_ctx->pool);
return SVN_NO_ERROR;
}
-static svn_error_t *
-cdata_options(svn_ra_serf__xml_parser_t *parser,
- const char *data,
- apr_size_t len,
- apr_pool_t *scratch_pool)
-{
- options_context_t *ctx = parser->user_data;
-
- if (ctx->collect_cdata)
- svn_stringbuf_appendbytes(ctx->acbuf, data, len);
-
- return SVN_NO_ERROR;
-}
static svn_error_t *
create_options_body(serf_bucket_t **body_bkt,
@@ -394,8 +300,7 @@ options_response_handler(serf_request_t
}
/* Execute the 'real' response handler to XML-parse the repsonse body. */
- return svn_ra_serf__handle_xml_parser(request, response,
- opt_ctx->parser_ctx, pool);
+ return opt_ctx->inner_handler(request, response, opt_ctx->inner_baton, pool);
}
@@ -406,22 +311,21 @@ create_options_req(options_context_t **o
apr_pool_t *pool)
{
options_context_t *new_ctx;
+ svn_ra_serf__xml_context_t *xmlctx;
svn_ra_serf__handler_t *handler;
- svn_ra_serf__xml_parser_t *parser_ctx;
new_ctx = apr_pcalloc(pool, sizeof(*new_ctx));
-
new_ctx->pool = pool;
-
- new_ctx->acbuf = svn_stringbuf_create_empty(pool);
- new_ctx->youngest_rev = SVN_INVALID_REVNUM;
-
new_ctx->session = session;
new_ctx->conn = conn;
- handler = apr_pcalloc(pool, sizeof(*handler));
+ new_ctx->youngest_rev = SVN_INVALID_REVNUM;
+
+ xmlctx = svn_ra_serf__xml_context_create(options_ttable,
+ NULL, options_closed, new_ctx,
+ pool);
+ handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
- handler->handler_pool = pool;
handler->method = "OPTIONS";
handler->path = session->session_url.path;
handler->body_delegate = create_options_body;
@@ -429,23 +333,13 @@ create_options_req(options_context_t **o
handler->conn = conn;
handler->session = session;
- parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
-
- parser_ctx->pool = pool;
- parser_ctx->user_data = new_ctx;
- parser_ctx->start = start_options;
- parser_ctx->end = end_options;
- parser_ctx->cdata = cdata_options;
- parser_ctx->done = &new_ctx->done;
-
new_ctx->handler = handler;
- new_ctx->parser_ctx = parser_ctx;
+ new_ctx->inner_handler = handler->response_handler;
+ new_ctx->inner_baton = handler->response_baton;
handler->response_handler = options_response_handler;
handler->response_baton = new_ctx;
- svn_ra_serf__request_create(handler);
-
*opt_ctx = new_ctx;
return SVN_NO_ERROR;
@@ -463,8 +357,7 @@ svn_ra_serf__v2_get_youngest_revnum(svn_
SVN_ERR_ASSERT(SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session));
SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
- SVN_ERR(svn_ra_serf__context_run_wait(&opt_ctx->done, session,
- scratch_pool));
+ SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool));
*youngest = opt_ctx->youngest_rev;
@@ -484,8 +377,7 @@ svn_ra_serf__v1_get_activity_collection(
SVN_ERR_ASSERT(!SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session));
SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
- SVN_ERR(svn_ra_serf__context_run_wait(&opt_ctx->done, session,
- scratch_pool));
+ SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool));
*activity_url = apr_pstrdup(result_pool, opt_ctx->activity_collection);
@@ -508,7 +400,7 @@ svn_ra_serf__exchange_capabilities(svn_r
/* This routine automatically fills in serf_sess->capabilities */
SVN_ERR(create_options_req(&opt_ctx, serf_sess, serf_sess->conns[0], pool));
- err = svn_ra_serf__context_run_wait(&opt_ctx->done, serf_sess, pool);
+ err = svn_ra_serf__context_run_one(opt_ctx->handler, pool);
/* If our caller cares about server redirections, and our response
carries such a thing, report as much. We'll disregard ERR --
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/property.c Mon May 14 14:07:45 2012
@@ -1088,8 +1088,6 @@ get_baseline_info(const char **bc_url,
revision (if needed) with an OPTIONS request. */
if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
{
- svn_revnum_t actual_revision;
-
if (SVN_IS_VALID_REVNUM(revision))
{
*revnum_used = revision;
@@ -1098,7 +1096,7 @@ get_baseline_info(const char **bc_url,
{
SVN_ERR(svn_ra_serf__v2_get_youngest_revnum(
revnum_used, conn, pool));
- if (! SVN_IS_VALID_REVNUM(actual_revision))
+ if (! SVN_IS_VALID_REVNUM(*revnum_used))
return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL,
_("The OPTIONS response did not include "
"the youngest revision"));
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/ra_serf.h Mon May 14 14:07:45 2012
@@ -26,7 +26,7 @@
#include <serf.h>
-#include <expat.h>
+#include <expat.h> /* for XML_Parser */
#include <apr_uri.h>
#include "svn_types.h"
@@ -608,6 +608,160 @@ struct svn_ra_serf__xml_parser_t {
apr_off_t read_size; /* Number of bytes read from response */
};
+
+/* v2 of the XML parsing functions */
+
+/* The XML parsing context. */
+typedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t;
+
+
+/* An opaque structure for the XML parse element/state. */
+typedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t;
+
+/* Called just after the parser moves into ENTERED_STATE. */
+typedef svn_error_t *
+(*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes,
+ void *baton,
+ int entered_state,
+ apr_pool_t *scratch_pool);
+
+
+/* Called just before the parser leaves LEAVING_STATE.
+
+ If cdata collection was enabled for this state, then CDATA will be
+ non-NULL and contain the collected cdata.
+
+ If attribute collection was enabled for this state, then ATTRS will
+ contain the attributes collected for this element only. Use
+ svn_ra_serf__xml_gather_since() to gather up data from outer states.
+ ATTRS is char* -> char*.
+
+ Temporary allocations may be made in SCRATCH_POOL. */
+typedef svn_error_t *
+(*svn_ra_serf__xml_closed_t)(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);
+
+
+/* State transition table.
+
+ When the XML Context is constructed, it is in state 0. User states are
+ positive integers.
+
+ In a list of transitions, use { 0 } to indicate the end. Specifically,
+ the code looks for NS == NULL.
+
+ ### more docco
+*/
+typedef struct svn_ra_serf__xml_transition_t {
+ /* This transition applies when in this state */
+ int from_state;
+
+ /* And when this tag is observed */
+ const char *ns;
+ const char *name;
+
+ /* Moving to this state */
+ int to_state;
+
+ /* Should the cdata of NAME be collected? */
+ svn_boolean_t collect_cdata;
+
+ /* Which attributes of NAME should be collected? Terminate with NULL.
+ Maximum of 10 attributes may be collected. Note that attribute
+ namespaces are ignored at this time.
+
+ Attribute names beginning with "?" are optional. Other names must
+ exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised. */
+ const char *collect_attrs[11];
+
+ /* When NAME is opened, should the callback be invoked? */
+ svn_boolean_t custom_open;
+
+ /* When NAME is closed, should the callback be invoked? */
+ svn_boolean_t custom_close;
+
+} svn_ra_serf__xml_transition_t;
+
+
+svn_ra_serf__xml_context_t *
+svn_ra_serf__xml_context_create(
+ const svn_ra_serf__xml_transition_t *ttable,
+ svn_ra_serf__xml_opened_t opened_cb,
+ svn_ra_serf__xml_closed_t closed_cb,
+ void *baton,
+ apr_pool_t *result_pool);
+
+
+/* Construct a handler with the response function/baton set up to parse
+ a response body using the given XML context. The handler and its
+ internal structures are allocated in RESULT_POOL.
+
+ This also initializes HANDLER_POOL to the given RESULT_POOL. */
+svn_ra_serf__handler_t *
+svn_ra_serf__create_expat_handler(svn_ra_serf__xml_context_t *xmlctx,
+ apr_pool_t *result_pool);
+
+
+/* Allocated within XES->STATE_POOL. Changes are not allowd. Make a deep
+ copy, as appropriate.
+
+ The resulting hash maps char* names to char* values. */
+apr_hash_t *
+svn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes,
+ int stop_state);
+
+
+/* Attach the NAME/VALUE pair onto this/parent state identified by STATE.
+ The name and value will be copied into the target state's pool.
+
+ These values will be available to the CLOSED_CB for the target state,
+ or part of the gathered state via xml_gather_since().
+
+ Typically, this function is used by a child state's close callback,
+ or within an opening callback to store additional data.
+
+ Note: if the state is not found, then a programmer error has occurred,
+ so the function will invoke SVN_ERR_MALFUNCTION(). */
+void
+svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
+ int state,
+ const char *name,
+ const char *value);
+
+
+/* Returns XES->STATE_POOL for allocating structures that should live
+ as long as the state identified by XES. */
+apr_pool_t *
+svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes);
+
+
+/* Any XML parser may be used. When an opening tag is seen, call this
+ function to feed the information into XMLCTX. */
+svn_error_t *
+svn_ra_serf__xml_cb_start(svn_ra_serf__xml_context_t *xmlctx,
+ const char *raw_name,
+ const char *const *attrs);
+
+
+/* When a close tag is seen, call this function to feed the information
+ into XMLCTX. */
+svn_error_t *
+svn_ra_serf__xml_cb_end(svn_ra_serf__xml_context_t *xmlctx,
+ const char *raw_name);
+
+
+/* When cdata is parsed by the wrapping XML parser, call this function to
+ feed the cdata into the XMLCTX. */
+svn_error_t *
+svn_ra_serf__xml_cb_cdata(svn_ra_serf__xml_context_t *xmlctx,
+ const char *data,
+ apr_size_t len);
+
+
/*
* Parses a server-side error message into a local Subversion error.
*/
@@ -814,12 +968,12 @@ svn_ra_serf__add_cdata_len_buckets(serf_
* Look up the @a attrs array for namespace definitions and add each one
* to the @a ns_list of namespaces.
*
- * New namespaces will be allocated in @a pool.
+ * New namespaces will be allocated in RESULT_POOL.
*/
void
svn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list,
- const char **attrs,
- apr_pool_t *pool);
+ const char *const *attrs,
+ apr_pool_t *result_pool);
/*
* Look up @a name in the @a ns_list list for previously declared namespace
@@ -830,7 +984,7 @@ svn_ra_serf__define_ns(svn_ra_serf__ns_t
*/
void
svn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name,
- svn_ra_serf__ns_t *ns_list,
+ const svn_ra_serf__ns_t *ns_list,
const char *name);
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/replay.c Mon May 14 14:07:45 2012
@@ -24,9 +24,6 @@
#include <apr_uri.h>
-
-#include <expat.h>
-
#include <serf.h>
#include "svn_pools.h"
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/serf.c Mon May 14 14:07:45 2012
@@ -27,9 +27,6 @@
#include <apr_want.h>
#include <apr_uri.h>
-
-#include <expat.h>
-
#include <serf.h>
#include "svn_pools.h"
Modified: subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c?rev=1338209&r1=1338208&r2=1338209&view=diff
==============================================================================
--- subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/ev2-export/subversion/libsvn_ra_serf/util.c Mon May 14 14:07:45 2012
@@ -33,6 +33,8 @@
#include <serf.h>
#include <serf_bucket_types.h>
+#include <expat.h>
+
#include "svn_dirent_uri.h"
#include "svn_path.h"
#include "svn_private_config.h"
@@ -56,6 +58,17 @@
#define XML_STATUS_ERROR 0
#endif
+#ifndef XML_VERSION_AT_LEAST
+#define XML_VERSION_AT_LEAST(major,minor,patch) \
+(((major) < XML_MAJOR_VERSION) \
+ || ((major) == XML_MAJOR_VERSION && (minor) < XML_MINOR_VERSION) \
+ || ((major) == XML_MAJOR_VERSION && (minor) == XML_MINOR_VERSION && \
+ (patch) <= XML_MICRO_VERSION))
+#endif /* APR_VERSION_AT_LEAST */
+
+#if XML_VERSION_AT_LEAST(1, 95, 8)
+#define EXPAT_HAS_STOPPARSER
+#endif
/* Read/write chunks of this size into the spillbuf. */
#define PARSE_CHUNK_SIZE 8000
@@ -80,6 +93,19 @@ struct svn_ra_serf__pending_t {
&& svn_spillbuf__get_size((p)->buf) != 0)
+struct expat_ctx_t {
+ svn_ra_serf__xml_context_t *xmlctx;
+ XML_Parser parser;
+ svn_ra_serf__handler_t *handler;
+
+ svn_error_t *inner_error;
+
+ /* Do not use this pool for allocation. It is merely recorded for running
+ the cleanup handler. */
+ apr_pool_t *cleanup_pool;
+};
+
+
static const apr_uint32_t serf_failure_map[][2] =
{
{ SERF_SSL_CERT_NOTYETVALID, SVN_AUTH_SSL_NOTYETVALID },
@@ -737,14 +763,21 @@ svn_error_t *
svn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler,
apr_pool_t *scratch_pool)
{
+ svn_error_t *err;
+
/* Create a serf request based on HANDLER. */
svn_ra_serf__request_create(handler);
/* Wait until the response logic marks its DONE status. */
- return svn_error_trace(svn_ra_serf__context_run_wait(
- &handler->done,
- handler->session,
- scratch_pool));
+ err = svn_ra_serf__context_run_wait(&handler->done, handler->session,
+ scratch_pool);
+ if (handler->server_error)
+ {
+ err = svn_error_compose_create(err, handler->server_error->error);
+ handler->server_error = NULL;
+ }
+
+ return svn_error_trace(err);
}
@@ -2247,3 +2280,175 @@ svn_ra_serf__register_editor_shim_callba
session->shim_callbacks = callbacks;
return SVN_NO_ERROR;
}
+
+
+/* Conforms to Expat's XML_StartElementHandler */
+static void
+expat_start(void *userData, const char *raw_name, const char **attrs)
+{
+ struct expat_ctx_t *ectx = userData;
+
+ if (ectx->inner_error != NULL)
+ return;
+
+ ectx->inner_error = svn_error_trace(
+ svn_ra_serf__xml_cb_start(ectx->xmlctx,
+ raw_name, attrs));
+
+#ifdef EXPAT_HAS_STOPPARSER
+ if (ectx->inner_error)
+ (void) XML_StopParser(ectx->parser, 0 /* resumable */);
+#endif
+}
+
+
+/* Conforms to Expat's XML_EndElementHandler */
+static void
+expat_end(void *userData, const char *raw_name)
+{
+ struct expat_ctx_t *ectx = userData;
+
+ if (ectx->inner_error != NULL)
+ return;
+
+ ectx->inner_error = svn_error_trace(
+ svn_ra_serf__xml_cb_end(ectx->xmlctx, raw_name));
+
+#ifdef EXPAT_HAS_STOPPARSER
+ if (ectx->inner_error)
+ (void) XML_StopParser(ectx->parser, 0 /* resumable */);
+#endif
+}
+
+
+/* Conforms to Expat's XML_CharacterDataHandler */
+static void
+expat_cdata(void *userData, const char *data, int len)
+{
+ struct expat_ctx_t *ectx = userData;
+
+ if (ectx->inner_error != NULL)
+ return;
+
+ ectx->inner_error = svn_error_trace(
+ svn_ra_serf__xml_cb_cdata(ectx->xmlctx, data, len));
+
+#ifdef EXPAT_HAS_STOPPARSER
+ if (ectx->inner_error)
+ (void) XML_StopParser(ectx->parser, 0 /* resumable */);
+#endif
+}
+
+
+/* Implements svn_ra_serf__response_handler_t */
+static svn_error_t *
+expat_response_handler(serf_request_t *request,
+ serf_bucket_t *response,
+ void *baton,
+ apr_pool_t *scratch_pool)
+{
+ struct expat_ctx_t *ectx = baton;
+
+ SVN_ERR_ASSERT(ectx->parser != NULL);
+
+ /* ### should we bail on anything < 200 or >= 300 ??
+ ### actually: < 200 should really be handled by the core. */
+ if (ectx->handler->sline.code == 404)
+ {
+ /* By deferring to expect_empty_body(), it will make a choice on
+ how to handle the body. Whatever the decision, the core handler
+ will take over, and we will not be called again. */
+ return svn_error_trace(svn_ra_serf__expect_empty_body(
+ request, response, ectx->handler,
+ scratch_pool));
+ }
+
+ while (1)
+ {
+ apr_status_t status;
+ const char *data;
+ apr_size_t len;
+ int expat_status;
+
+ status = serf_bucket_read(response, PARSE_CHUNK_SIZE, &data, &len);
+ if (SERF_BUCKET_READ_ERROR(status))
+ return svn_error_wrap_apr(status, NULL);
+
+#if 0
+ /* ### move restart/skip into the core handler */
+ ectx->handler->read_size += len;
+#endif
+
+ /* ### move PAUSED behavior to a new response handler that can feed
+ ### an inner handler, or can pause for a while. */
+
+ /* ### should we have an IGNORE_ERRORS flag like the v1 parser? */
+
+ expat_status = XML_Parse(ectx->parser, data, (int)len, 0 /* isFinal */);
+ if (expat_status == XML_STATUS_ERROR)
+ return svn_error_createf(SVN_ERR_XML_MALFORMED, NULL,
+ _("The %s response contains invalid XML"
+ " (%d %s)"),
+ ectx->handler->method,
+ ectx->handler->sline.code,
+ ectx->handler->sline.reason);
+
+ /* Was an error dropped off for us? */
+ if (ectx->inner_error)
+ {
+ apr_pool_cleanup_run(ectx->cleanup_pool, &ectx->parser,
+ xml_parser_cleanup);
+ return svn_error_trace(ectx->inner_error);
+ }
+
+ /* The parsing went fine. What has the bucket told us? */
+
+ if (APR_STATUS_IS_EAGAIN(status))
+ return svn_error_wrap_apr(status, NULL);
+
+ if (APR_STATUS_IS_EOF(status))
+ {
+ /* Tell expat we've reached the end of the content. Ignore the
+ return status. We just don't care. */
+ (void) XML_Parse(ectx->parser, NULL, 0, 1 /* isFinal */);
+
+ apr_pool_cleanup_run(ectx->cleanup_pool, &ectx->parser,
+ xml_parser_cleanup);
+
+ /* ### should check XMLCTX to see if it has returned to the
+ ### INITIAL state. we may have ended early... */
+
+ return svn_error_wrap_apr(status, NULL);
+ }
+ }
+
+ /* NOTREACHED */
+}
+
+
+svn_ra_serf__handler_t *
+svn_ra_serf__create_expat_handler(svn_ra_serf__xml_context_t *xmlctx,
+ apr_pool_t *result_pool)
+{
+ svn_ra_serf__handler_t *handler;
+ struct expat_ctx_t *ectx;
+
+ ectx = apr_pcalloc(result_pool, sizeof(*ectx));
+ ectx->xmlctx = xmlctx;
+ ectx->parser = XML_ParserCreate(NULL);
+ apr_pool_cleanup_register(result_pool, &ectx->parser,
+ xml_parser_cleanup, apr_pool_cleanup_null);
+ XML_SetUserData(ectx->parser, ectx);
+ XML_SetElementHandler(ectx->parser, expat_start, expat_end);
+ XML_SetCharacterDataHandler(ectx->parser, expat_cdata);
+
+
+ handler = apr_pcalloc(result_pool, sizeof(*handler));
+ handler->handler_pool = result_pool;
+ handler->response_handler = expat_response_handler;
+ handler->response_baton = ectx;
+
+ ectx->handler = handler;
+
+ return handler;
+}