2 * getlocations.c : entry point for get_locations RA functions for ra_serf
4 * ====================================================================
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
21 * ====================================================================
32 #include "svn_pools.h"
35 #include "svn_private_config.h"
37 #include "../libsvn_ra/ra_loader.h"
43 * This enum represents the current state of our XML parsing for a REPORT.
51 typedef struct loc_context_t {
52 /* pool to allocate memory from */
55 /* parameters set by our caller */
57 const apr_array_header_t *location_revisions;
58 svn_revnum_t peg_revision;
60 /* Returned location hash */
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 },
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));
107 /* Implements svn_ra_serf__request_body_delegate_t */
109 create_get_locations_body(serf_bucket_t **body_bkt,
111 serf_bucket_alloc_t *alloc,
114 serf_bucket_t *buckets;
115 loc_context_t *loc_ctx = baton;
118 buckets = serf_bucket_aggregate_create(alloc);
120 svn_ra_serf__add_open_tag_buckets(buckets, alloc,
122 "xmlns:S", SVN_XML_NAMESPACE,
126 svn_ra_serf__add_tag_buckets(buckets,
127 "S:path", loc_ctx->path,
130 svn_ra_serf__add_tag_buckets(buckets,
131 "S:peg-revision", apr_ltoa(pool, loc_ctx->peg_revision),
134 for (i = 0; i < loc_ctx->location_revisions->nelts; i++)
136 svn_revnum_t rev = APR_ARRAY_IDX(loc_ctx->location_revisions, i, svn_revnum_t);
137 svn_ra_serf__add_tag_buckets(buckets,
138 "S:location-revision", apr_ltoa(pool, rev),
142 svn_ra_serf__add_close_tag_buckets(buckets, alloc,
150 svn_ra_serf__get_locations(svn_ra_session_t *ra_session,
151 apr_hash_t **locations,
153 svn_revnum_t peg_revision,
154 const apr_array_header_t *location_revisions,
157 loc_context_t *loc_ctx;
158 svn_ra_serf__session_t *session = ra_session->priv;
159 svn_ra_serf__handler_t *handler;
160 svn_ra_serf__xml_context_t *xmlctx;
164 loc_ctx = apr_pcalloc(pool, sizeof(*loc_ctx));
165 loc_ctx->pool = pool;
166 loc_ctx->path = path;
167 loc_ctx->peg_revision = peg_revision;
168 loc_ctx->location_revisions = location_revisions;
169 loc_ctx->paths = apr_hash_make(loc_ctx->pool);
171 *locations = loc_ctx->paths;
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);
184 handler->method = "REPORT";
185 handler->path = req_url;
186 handler->body_delegate = create_get_locations_body;
187 handler->body_delegate_baton = loc_ctx;
188 handler->body_type = "text/xml";
189 handler->conn = session->conns[0];
190 handler->session = session;
192 err = svn_ra_serf__context_run_one(handler, pool);
194 SVN_ERR(svn_error_compose_create(
195 svn_ra_serf__error_on_status(handler->sline,