66
60
/* Returned location hash */
69
/* Current state we're in */
70
loc_state_list_t *state;
71
loc_state_list_t *free_state;
66
#define S_ SVN_XML_NAMESPACE
67
static const svn_ra_serf__xml_transition_t getloc_ttable[] = {
68
{ INITIAL, S_, "get-locations-report", REPORT,
69
FALSE, { NULL }, FALSE },
71
{ REPORT, S_, "location", LOCATION,
72
FALSE, { "?rev", "?path", NULL }, TRUE },
80
push_state(loc_context_t *loc_ctx, loc_state_e state)
82
loc_state_list_t *new_state;
84
if (!loc_ctx->free_state)
86
new_state = apr_palloc(loc_ctx->pool, sizeof(*loc_ctx->state));
90
new_state = loc_ctx->free_state;
91
loc_ctx->free_state = loc_ctx->free_state->prev;
93
new_state->state = state;
95
/* Add it to the state chain. */
96
new_state->prev = loc_ctx->state;
97
loc_ctx->state = new_state;
100
static void pop_state(loc_context_t *loc_ctx)
102
loc_state_list_t *free_state;
103
free_state = loc_ctx->state;
104
/* advance the current state */
105
loc_ctx->state = loc_ctx->state->prev;
106
free_state->prev = loc_ctx->free_state;
107
loc_ctx->free_state = free_state;
111
start_getloc(svn_ra_serf__xml_parser_t *parser,
113
svn_ra_serf__dav_props_t name,
116
loc_context_t *loc_ctx = userData;
118
if (!loc_ctx->state && strcmp(name.name, "get-locations-report") == 0)
120
push_state(loc_ctx, REPORT);
122
else if (loc_ctx->state &&
123
loc_ctx->state->state == REPORT &&
124
strcmp(name.name, "location") == 0)
126
svn_revnum_t rev = SVN_INVALID_REVNUM;
127
const char *revstr, *path;
129
revstr = svn_xml_get_attr_value("rev", attrs);
132
rev = SVN_STR_TO_REV(revstr);
135
path = svn_xml_get_attr_value("path", attrs);
137
if (SVN_IS_VALID_REVNUM(rev) && path)
139
apr_hash_set(loc_ctx->paths,
140
apr_pmemdup(loc_ctx->pool, &rev, sizeof(rev)),
142
apr_pstrdup(loc_ctx->pool, path));
150
end_getloc(svn_ra_serf__xml_parser_t *parser,
152
svn_ra_serf__dav_props_t name)
154
loc_context_t *loc_ctx = userData;
155
loc_state_list_t *cur_state;
162
cur_state = loc_ctx->state;
164
if (cur_state->state == REPORT &&
165
strcmp(name.name, "get-locations-report") == 0)
169
else if (cur_state->state == LOCATION &&
170
strcmp(name.name, "location") == 0)
78
/* Conforms to svn_ra_serf__xml_closed_t */
80
getloc_closed(svn_ra_serf__xml_estate_t *xes,
83
const svn_string_t *cdata,
85
apr_pool_t *scratch_pool)
87
loc_context_t *loc_ctx = baton;
91
SVN_ERR_ASSERT(leaving_state == LOCATION);
93
revstr = svn_hash_gets(attrs, "rev");
94
path = svn_hash_gets(attrs, "path");
95
if (revstr != NULL && path != NULL)
97
svn_revnum_t rev = SVN_STR_TO_REV(revstr);
98
apr_hash_set(loc_ctx->paths,
99
apr_pmemdup(loc_ctx->pool, &rev, sizeof(rev)), sizeof(rev),
100
apr_pstrdup(loc_ctx->pool, path));
178
107
/* Implements svn_ra_serf__request_body_delegate_t */
179
108
static svn_error_t *
237
166
loc_ctx->path = path;
238
167
loc_ctx->peg_revision = peg_revision;
239
168
loc_ctx->location_revisions = location_revisions;
240
loc_ctx->done = FALSE;
241
169
loc_ctx->paths = apr_hash_make(loc_ctx->pool);
243
171
*locations = loc_ctx->paths;
245
SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url, &relative_url, session,
246
NULL, NULL, peg_revision, NULL,
249
req_url = svn_path_url_add_component2(basecoll_url, relative_url, pool);
251
handler = apr_pcalloc(pool, sizeof(*handler));
173
SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
174
session, NULL /* conn */,
175
NULL /* url */, peg_revision,
178
xmlctx = svn_ra_serf__xml_context_create(getloc_ttable,
179
NULL, getloc_closed, NULL,
182
handler = svn_ra_serf__create_expat_handler(xmlctx, pool);
253
184
handler->method = "REPORT";
254
185
handler->path = req_url;
258
189
handler->conn = session->conns[0];
259
190
handler->session = session;
261
parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
263
parser_ctx->pool = pool;
264
parser_ctx->user_data = loc_ctx;
265
parser_ctx->start = start_getloc;
266
parser_ctx->end = end_getloc;
267
parser_ctx->status_code = &loc_ctx->status_code;
268
parser_ctx->done = &loc_ctx->done;
270
handler->response_handler = svn_ra_serf__handle_xml_parser;
271
handler->response_baton = parser_ctx;
273
svn_ra_serf__request_create(handler);
275
err = svn_ra_serf__context_run_wait(&loc_ctx->done, session, pool);
192
err = svn_ra_serf__context_run_one(handler, pool);
277
194
SVN_ERR(svn_error_compose_create(
278
svn_ra_serf__error_on_status(loc_ctx->status_code,
195
svn_ra_serf__error_on_status(handler->sline,
280
parser_ctx->location),
283
200
return SVN_NO_ERROR;