2 * getlocationsegments.c : entry point for get_location_segments
3 * RA functions for ra_serf
5 * ====================================================================
6 * Copyright (c) 2007 CollabNet. All rights reserved.
8 * This software is licensed as described in the file COPYING, which
9 * you should have received as part of this distribution. The terms
10 * are also available at http://subversion.tigris.org/license-1.html.
11 * If newer versions of this license are posted there, you may use a
12 * newer version instead, at your option.
14 * This software consists of voluntary contributions made by many
15 * individuals. For exact contribution history, see the revision
16 * history and logs, available at http://subversion.tigris.org/.
17 * ====================================================================
26 #include "svn_pools.h"
30 #include "svn_private_config.h"
31 #include "../libsvn_ra/ra_loader.h"
38 /* location segment callback function/baton */
39 svn_location_segment_receiver_t receiver
;
42 /* subpool used only as long as a single receiver invocation */
45 /* True iff we're looking at a child of the outer report tag */
46 svn_boolean_t inside_report
;
48 /* Return error code */
58 start_gls(svn_ra_serf__xml_parser_t
*parser
,
60 svn_ra_serf__dav_props_t name
,
63 gls_context_t
*gls_ctx
= userData
;
65 if ((! gls_ctx
->inside_report
)
66 && strcmp(name
.name
, "get-location-segments-report") == 0)
68 gls_ctx
->inside_report
= TRUE
;
70 else if (gls_ctx
->inside_report
71 && strcmp(name
.name
, "location-segment") == 0)
74 svn_revnum_t range_start
= SVN_INVALID_REVNUM
;
75 svn_revnum_t range_end
= SVN_INVALID_REVNUM
;
76 const char *path
= NULL
;
78 path
= svn_xml_get_attr_value("path", attrs
);
79 rev_str
= svn_xml_get_attr_value("range-start", attrs
);
81 range_start
= SVN_STR_TO_REV(rev_str
);
82 rev_str
= svn_xml_get_attr_value("range-end", attrs
);
84 range_end
= SVN_STR_TO_REV(rev_str
);
86 if (SVN_IS_VALID_REVNUM(range_start
) && SVN_IS_VALID_REVNUM(range_end
))
88 svn_location_segment_t
*segment
= apr_pcalloc(gls_ctx
->subpool
,
91 segment
->range_start
= range_start
;
92 segment
->range_end
= range_end
;
93 SVN_ERR(gls_ctx
->receiver(segment
,
94 gls_ctx
->receiver_baton
,
96 svn_pool_clear(gls_ctx
->subpool
);
100 return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA
, NULL
,
101 _("Expected valid revision range"));
109 end_gls(svn_ra_serf__xml_parser_t
*parser
,
111 svn_ra_serf__dav_props_t name
)
113 gls_context_t
*gls_ctx
= userData
;
115 if (strcmp(name
.name
, "get-location-segments-report") == 0)
116 gls_ctx
->inside_report
= FALSE
;
122 svn_ra_serf__get_location_segments(svn_ra_session_t
*ra_session
,
124 svn_revnum_t peg_revision
,
125 svn_revnum_t start_rev
,
126 svn_revnum_t end_rev
,
127 svn_location_segment_receiver_t receiver
,
128 void *receiver_baton
,
131 gls_context_t
*gls_ctx
;
132 svn_ra_serf__session_t
*session
= ra_session
->priv
;
133 svn_ra_serf__handler_t
*handler
;
134 svn_ra_serf__xml_parser_t
*parser_ctx
;
135 serf_bucket_t
*buckets
, *tmp
;
136 const char *relative_url
, *basecoll_url
, *req_url
;
139 gls_ctx
= apr_pcalloc(pool
, sizeof(*gls_ctx
));
140 gls_ctx
->receiver
= receiver
;
141 gls_ctx
->receiver_baton
= receiver_baton
;
142 gls_ctx
->subpool
= svn_pool_create(pool
);
143 gls_ctx
->inside_report
= FALSE
;
144 gls_ctx
->error
= SVN_NO_ERROR
;
145 gls_ctx
->done
= FALSE
;
147 buckets
= serf_bucket_aggregate_create(session
->bkt_alloc
);
149 tmp
= SERF_BUCKET_SIMPLE_STRING_LEN("<S:get-location-segments xmlns:S=\"",
150 sizeof("<S:get-location-segments "
153 serf_bucket_aggregate_append(buckets
, tmp
);
155 tmp
= SERF_BUCKET_SIMPLE_STRING_LEN(SVN_XML_NAMESPACE
,
156 sizeof(SVN_XML_NAMESPACE
)-1,
158 serf_bucket_aggregate_append(buckets
, tmp
);
160 tmp
= SERF_BUCKET_SIMPLE_STRING_LEN("\">",
163 serf_bucket_aggregate_append(buckets
, tmp
);
165 svn_ra_serf__add_tag_buckets(buckets
,
169 svn_ra_serf__add_tag_buckets(buckets
,
171 apr_ltoa(pool
, peg_revision
),
174 svn_ra_serf__add_tag_buckets(buckets
,
176 apr_ltoa(pool
, start_rev
),
179 svn_ra_serf__add_tag_buckets(buckets
,
181 apr_ltoa(pool
, end_rev
),
184 tmp
= SERF_BUCKET_SIMPLE_STRING_LEN("</S:get-location-segments>",
185 sizeof("</S:get-location-segments>")-1,
187 serf_bucket_aggregate_append(buckets
, tmp
);
189 SVN_ERR(svn_ra_serf__get_baseline_info(&basecoll_url
, &relative_url
,
190 session
, NULL
, peg_revision
, pool
));
192 req_url
= svn_path_url_add_component(basecoll_url
, relative_url
, pool
);
194 handler
= apr_pcalloc(pool
, sizeof(*handler
));
196 handler
->method
= "REPORT";
197 handler
->path
= req_url
;
198 handler
->body_buckets
= buckets
;
199 handler
->body_type
= "text/xml";
200 handler
->conn
= session
->conns
[0];
201 handler
->session
= session
;
203 parser_ctx
= apr_pcalloc(pool
, sizeof(*parser_ctx
));
205 parser_ctx
->pool
= pool
;
206 parser_ctx
->user_data
= gls_ctx
;
207 parser_ctx
->start
= start_gls
;
208 parser_ctx
->end
= end_gls
;
209 parser_ctx
->status_code
= &gls_ctx
->status_code
;
210 parser_ctx
->done
= &gls_ctx
->done
;
212 handler
->response_handler
= svn_ra_serf__handle_xml_parser
;
213 handler
->response_baton
= parser_ctx
;
215 svn_ra_serf__request_create(handler
);
217 err
= svn_ra_serf__context_run_wait(&gls_ctx
->done
, session
, pool
);
219 if (gls_ctx
->error
|| parser_ctx
->error
)
221 svn_error_clear(err
);
223 SVN_ERR(gls_ctx
->error
);
224 SVN_ERR(parser_ctx
->error
);
227 svn_pool_destroy(gls_ctx
->subpool
);
229 if (err
&& (err
->apr_err
== SVN_ERR_UNSUPPORTED_FEATURE
))
230 return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED
, err
, NULL
);