1251881Speter/* 2251881Speter * get_deleted_rev.c : ra_serf get_deleted_rev API implementation. 3251881Speter * 4251881Speter * ==================================================================== 5251881Speter * Licensed to the Apache Software Foundation (ASF) under one 6251881Speter * or more contributor license agreements. See the NOTICE file 7251881Speter * distributed with this work for additional information 8251881Speter * regarding copyright ownership. The ASF licenses this file 9251881Speter * to you under the Apache License, Version 2.0 (the 10251881Speter * "License"); you may not use this file except in compliance 11251881Speter * with the License. You may obtain a copy of the License at 12251881Speter * 13251881Speter * http://www.apache.org/licenses/LICENSE-2.0 14251881Speter * 15251881Speter * Unless required by applicable law or agreed to in writing, 16251881Speter * software distributed under the License is distributed on an 17251881Speter * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18251881Speter * KIND, either express or implied. See the License for the 19251881Speter * specific language governing permissions and limitations 20251881Speter * under the License. 21251881Speter * ==================================================================== 22251881Speter */ 23251881Speter 24251881Speter 25251881Speter#include "svn_ra.h" 26251881Speter#include "svn_xml.h" 27251881Speter#include "svn_path.h" 28251881Speter#include "svn_private_config.h" 29251881Speter 30251881Speter#include "../libsvn_ra/ra_loader.h" 31251881Speter 32251881Speter#include "ra_serf.h" 33251881Speter 34251881Speter 35251881Speter/* 36251881Speter * This enum represents the current state of our XML parsing for a REPORT. 37251881Speter */ 38251881Speterenum drev_state_e { 39299742Sdim INITIAL = XML_STATE_INITIAL, 40251881Speter REPORT, 41251881Speter VERSION_NAME 42251881Speter}; 43251881Speter 44251881Spetertypedef struct drev_context_t { 45251881Speter const char *path; 46251881Speter svn_revnum_t peg_revision; 47251881Speter svn_revnum_t end_revision; 48251881Speter 49251881Speter /* What revision was PATH@PEG_REVISION first deleted within 50251881Speter the range PEG_REVISION-END-END_REVISION? */ 51251881Speter svn_revnum_t *revision_deleted; 52251881Speter 53251881Speter} drev_context_t; 54251881Speter 55251881Speter#define D_ "DAV:" 56251881Speter#define S_ SVN_XML_NAMESPACE 57251881Speterstatic const svn_ra_serf__xml_transition_t getdrev_ttable[] = { 58251881Speter { INITIAL, S_, "get-deleted-rev-report", REPORT, 59251881Speter FALSE, { NULL }, FALSE }, 60251881Speter 61251881Speter { REPORT, D_, SVN_DAV__VERSION_NAME, VERSION_NAME, 62251881Speter TRUE, { NULL }, TRUE }, 63251881Speter 64251881Speter { 0 } 65251881Speter}; 66251881Speter 67251881Speter 68251881Speter/* Conforms to svn_ra_serf__xml_closed_t */ 69251881Speterstatic svn_error_t * 70251881Spetergetdrev_closed(svn_ra_serf__xml_estate_t *xes, 71251881Speter void *baton, 72251881Speter int leaving_state, 73251881Speter const svn_string_t *cdata, 74251881Speter apr_hash_t *attrs, 75251881Speter apr_pool_t *scratch_pool) 76251881Speter{ 77251881Speter drev_context_t *drev_ctx = baton; 78299742Sdim apr_int64_t rev; 79251881Speter 80251881Speter SVN_ERR_ASSERT(leaving_state == VERSION_NAME); 81251881Speter SVN_ERR_ASSERT(cdata != NULL); 82251881Speter 83299742Sdim SVN_ERR(svn_cstring_atoi64(&rev, cdata->data)); 84299742Sdim *drev_ctx->revision_deleted = (svn_revnum_t)rev; 85251881Speter 86251881Speter return SVN_NO_ERROR; 87251881Speter} 88251881Speter 89251881Speter 90251881Speter/* Implements svn_ra_serf__request_body_delegate_t */ 91251881Speterstatic svn_error_t * 92251881Spetercreate_getdrev_body(serf_bucket_t **body_bkt, 93251881Speter void *baton, 94251881Speter serf_bucket_alloc_t *alloc, 95299742Sdim apr_pool_t *pool /* request pool */, 96299742Sdim apr_pool_t *scratch_pool) 97251881Speter{ 98251881Speter serf_bucket_t *buckets; 99251881Speter drev_context_t *drev_ctx = baton; 100251881Speter 101251881Speter buckets = serf_bucket_aggregate_create(alloc); 102251881Speter 103251881Speter svn_ra_serf__add_open_tag_buckets(buckets, alloc, 104251881Speter "S:get-deleted-rev-report", 105251881Speter "xmlns:S", SVN_XML_NAMESPACE, 106251881Speter "xmlns:D", "DAV:", 107299742Sdim SVN_VA_NULL); 108251881Speter 109251881Speter svn_ra_serf__add_tag_buckets(buckets, 110251881Speter "S:path", drev_ctx->path, 111251881Speter alloc); 112251881Speter 113251881Speter svn_ra_serf__add_tag_buckets(buckets, 114251881Speter "S:peg-revision", 115251881Speter apr_ltoa(pool, drev_ctx->peg_revision), 116251881Speter alloc); 117251881Speter 118251881Speter svn_ra_serf__add_tag_buckets(buckets, 119251881Speter "S:end-revision", 120251881Speter apr_ltoa(pool, drev_ctx->end_revision), 121251881Speter alloc); 122251881Speter 123251881Speter svn_ra_serf__add_close_tag_buckets(buckets, alloc, 124251881Speter "S:get-deleted-rev-report"); 125251881Speter 126251881Speter *body_bkt = buckets; 127251881Speter return SVN_NO_ERROR; 128251881Speter} 129251881Speter 130251881Spetersvn_error_t * 131251881Spetersvn_ra_serf__get_deleted_rev(svn_ra_session_t *session, 132251881Speter const char *path, 133251881Speter svn_revnum_t peg_revision, 134251881Speter svn_revnum_t end_revision, 135251881Speter svn_revnum_t *revision_deleted, 136251881Speter apr_pool_t *pool) 137251881Speter{ 138251881Speter drev_context_t *drev_ctx; 139251881Speter svn_ra_serf__session_t *ras = session->priv; 140251881Speter svn_ra_serf__handler_t *handler; 141251881Speter svn_ra_serf__xml_context_t *xmlctx; 142251881Speter const char *req_url; 143251881Speter svn_error_t *err; 144251881Speter 145251881Speter drev_ctx = apr_pcalloc(pool, sizeof(*drev_ctx)); 146251881Speter drev_ctx->path = path; 147251881Speter drev_ctx->peg_revision = peg_revision; 148251881Speter drev_ctx->end_revision = end_revision; 149251881Speter drev_ctx->revision_deleted = revision_deleted; 150251881Speter 151251881Speter SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */, 152299742Sdim ras, NULL /* url */, peg_revision, 153251881Speter pool, pool)); 154251881Speter 155251881Speter xmlctx = svn_ra_serf__xml_context_create(getdrev_ttable, 156251881Speter NULL, getdrev_closed, NULL, 157251881Speter drev_ctx, 158251881Speter pool); 159299742Sdim handler = svn_ra_serf__create_expat_handler(ras, xmlctx, NULL, pool); 160251881Speter 161251881Speter handler->method = "REPORT"; 162251881Speter handler->path = req_url; 163251881Speter handler->body_type = "text/xml"; 164251881Speter handler->body_delegate = create_getdrev_body; 165251881Speter handler->body_delegate_baton = drev_ctx; 166251881Speter 167251881Speter err = svn_ra_serf__context_run_one(handler, pool); 168251881Speter 169251881Speter /* Map status 501: Method Not Implemented to our not implemented error. 170251881Speter 1.5.x servers and older don't support this report. */ 171251881Speter if (handler->sline.code == 501) 172251881Speter return svn_error_createf(SVN_ERR_RA_NOT_IMPLEMENTED, err, 173251881Speter _("'%s' REPORT not implemented"), 174251881Speter "get-deleted-rev"); 175251881Speter SVN_ERR(err); 176251881Speter 177251881Speter return SVN_NO_ERROR; 178251881Speter} 179