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.
46 INITIAL = XML_STATE_INITIAL,
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)
100 SVN_ERR(svn_cstring_atoi64(&rev_val, revstr));
101 rev = (svn_revnum_t)rev_val;
103 apr_hash_set(loc_ctx->paths,
104 apr_pmemdup(loc_ctx->pool, &rev, sizeof(rev)), sizeof(rev),
105 apr_pstrdup(loc_ctx->pool, path));
112 /* Implements svn_ra_serf__request_body_delegate_t */
114 create_get_locations_body(serf_bucket_t **body_bkt,
116 serf_bucket_alloc_t *alloc,
117 apr_pool_t *pool /* request pool */,
118 apr_pool_t *scratch_pool)
120 serf_bucket_t *buckets;
121 loc_context_t *loc_ctx = baton;
124 buckets = serf_bucket_aggregate_create(alloc);
126 svn_ra_serf__add_open_tag_buckets(buckets, alloc,
128 "xmlns:S", SVN_XML_NAMESPACE,
132 svn_ra_serf__add_tag_buckets(buckets,
133 "S:path", loc_ctx->path,
136 svn_ra_serf__add_tag_buckets(buckets,
137 "S:peg-revision", apr_ltoa(pool, loc_ctx->peg_revision),
140 for (i = 0; i < loc_ctx->location_revisions->nelts; i++)
142 svn_revnum_t rev = APR_ARRAY_IDX(loc_ctx->location_revisions, i, svn_revnum_t);
143 svn_ra_serf__add_tag_buckets(buckets,
144 "S:location-revision", apr_ltoa(pool, rev),
148 svn_ra_serf__add_close_tag_buckets(buckets, alloc,
156 svn_ra_serf__get_locations(svn_ra_session_t *ra_session,
157 apr_hash_t **locations,
159 svn_revnum_t peg_revision,
160 const apr_array_header_t *location_revisions,
163 loc_context_t *loc_ctx;
164 svn_ra_serf__session_t *session = ra_session->priv;
165 svn_ra_serf__handler_t *handler;
166 svn_ra_serf__xml_context_t *xmlctx;
169 loc_ctx = apr_pcalloc(pool, sizeof(*loc_ctx));
170 loc_ctx->pool = pool;
171 loc_ctx->path = path;
172 loc_ctx->peg_revision = peg_revision;
173 loc_ctx->location_revisions = location_revisions;
174 loc_ctx->paths = apr_hash_make(loc_ctx->pool);
176 *locations = loc_ctx->paths;
178 SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
179 session, NULL /* url */, peg_revision,
182 xmlctx = svn_ra_serf__xml_context_create(getloc_ttable,
183 NULL, getloc_closed, NULL,
186 handler = svn_ra_serf__create_expat_handler(session, xmlctx, NULL, pool);
188 handler->method = "REPORT";
189 handler->path = req_url;
190 handler->body_delegate = create_get_locations_body;
191 handler->body_delegate_baton = loc_ctx;
192 handler->body_type = "text/xml";
194 SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
196 if (handler->sline.code != 200)
197 SVN_ERR(svn_ra_serf__unexpected_status(handler));