1/* 2 * cancel.c: Routines to support cancellation of running subversion functions. 3 * 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 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 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 20 * under the License. 21 * ==================================================================== 22 */ 23 24#include "svn_delta.h" 25 26struct edit_baton 27{ 28 const svn_delta_editor_t *wrapped_editor; 29 void *wrapped_edit_baton; 30 31 svn_cancel_func_t cancel_func; 32 void *cancel_baton; 33}; 34 35struct dir_baton 36{ 37 void *edit_baton; 38 void *wrapped_dir_baton; 39}; 40 41struct file_baton 42{ 43 void *edit_baton; 44 void *wrapped_file_baton; 45}; 46 47static svn_error_t * 48set_target_revision(void *edit_baton, 49 svn_revnum_t target_revision, 50 apr_pool_t *pool) 51{ 52 struct edit_baton *eb = edit_baton; 53 54 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 55 56 return eb->wrapped_editor->set_target_revision(eb->wrapped_edit_baton, 57 target_revision, 58 pool); 59} 60 61static svn_error_t * 62open_root(void *edit_baton, 63 svn_revnum_t base_revision, 64 apr_pool_t *pool, 65 void **root_baton) 66{ 67 struct edit_baton *eb = edit_baton; 68 struct dir_baton *dir_baton = apr_palloc(pool, sizeof(*dir_baton)); 69 70 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 71 72 SVN_ERR(eb->wrapped_editor->open_root(eb->wrapped_edit_baton, 73 base_revision, 74 pool, 75 &dir_baton->wrapped_dir_baton)); 76 77 dir_baton->edit_baton = edit_baton; 78 79 *root_baton = dir_baton; 80 81 return SVN_NO_ERROR; 82} 83 84static svn_error_t * 85delete_entry(const char *path, 86 svn_revnum_t base_revision, 87 void *parent_baton, 88 apr_pool_t *pool) 89{ 90 struct dir_baton *pb = parent_baton; 91 struct edit_baton *eb = pb->edit_baton; 92 93 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 94 95 return eb->wrapped_editor->delete_entry(path, 96 base_revision, 97 pb->wrapped_dir_baton, 98 pool); 99} 100 101static svn_error_t * 102add_directory(const char *path, 103 void *parent_baton, 104 const char *copyfrom_path, 105 svn_revnum_t copyfrom_revision, 106 apr_pool_t *pool, 107 void **child_baton) 108{ 109 struct dir_baton *pb = parent_baton; 110 struct edit_baton *eb = pb->edit_baton; 111 struct dir_baton *b = apr_palloc(pool, sizeof(*b)); 112 113 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 114 115 SVN_ERR(eb->wrapped_editor->add_directory(path, 116 pb->wrapped_dir_baton, 117 copyfrom_path, 118 copyfrom_revision, 119 pool, 120 &b->wrapped_dir_baton)); 121 122 b->edit_baton = eb; 123 *child_baton = b; 124 125 return SVN_NO_ERROR; 126} 127 128static svn_error_t * 129open_directory(const char *path, 130 void *parent_baton, 131 svn_revnum_t base_revision, 132 apr_pool_t *pool, 133 void **child_baton) 134{ 135 struct dir_baton *pb = parent_baton; 136 struct edit_baton *eb = pb->edit_baton; 137 struct dir_baton *db = apr_palloc(pool, sizeof(*db)); 138 139 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 140 141 SVN_ERR(eb->wrapped_editor->open_directory(path, 142 pb->wrapped_dir_baton, 143 base_revision, 144 pool, 145 &db->wrapped_dir_baton)); 146 147 db->edit_baton = eb; 148 *child_baton = db; 149 150 return SVN_NO_ERROR; 151} 152 153static svn_error_t * 154add_file(const char *path, 155 void *parent_baton, 156 const char *copyfrom_path, 157 svn_revnum_t copyfrom_revision, 158 apr_pool_t *pool, 159 void **file_baton) 160{ 161 struct dir_baton *pb = parent_baton; 162 struct edit_baton *eb = pb->edit_baton; 163 struct file_baton *fb = apr_palloc(pool, sizeof(*fb)); 164 165 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 166 167 SVN_ERR(eb->wrapped_editor->add_file(path, 168 pb->wrapped_dir_baton, 169 copyfrom_path, 170 copyfrom_revision, 171 pool, 172 &fb->wrapped_file_baton)); 173 174 fb->edit_baton = eb; 175 *file_baton = fb; 176 177 return SVN_NO_ERROR; 178} 179 180static svn_error_t * 181open_file(const char *path, 182 void *parent_baton, 183 svn_revnum_t base_revision, 184 apr_pool_t *pool, 185 void **file_baton) 186{ 187 struct dir_baton *pb = parent_baton; 188 struct edit_baton *eb = pb->edit_baton; 189 struct file_baton *fb = apr_palloc(pool, sizeof(*fb)); 190 191 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 192 193 SVN_ERR(eb->wrapped_editor->open_file(path, 194 pb->wrapped_dir_baton, 195 base_revision, 196 pool, 197 &fb->wrapped_file_baton)); 198 199 fb->edit_baton = eb; 200 *file_baton = fb; 201 202 return SVN_NO_ERROR; 203} 204 205static svn_error_t * 206apply_textdelta(void *file_baton, 207 const char *base_checksum, 208 apr_pool_t *pool, 209 svn_txdelta_window_handler_t *handler, 210 void **handler_baton) 211{ 212 struct file_baton *fb = file_baton; 213 struct edit_baton *eb = fb->edit_baton; 214 215 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 216 217 return eb->wrapped_editor->apply_textdelta(fb->wrapped_file_baton, 218 base_checksum, 219 pool, 220 handler, 221 handler_baton); 222} 223 224static svn_error_t * 225close_file(void *file_baton, 226 const char *text_checksum, 227 apr_pool_t *pool) 228{ 229 struct file_baton *fb = file_baton; 230 struct edit_baton *eb = fb->edit_baton; 231 232 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 233 234 return eb->wrapped_editor->close_file(fb->wrapped_file_baton, 235 text_checksum, pool); 236} 237 238static svn_error_t * 239absent_file(const char *path, 240 void *file_baton, 241 apr_pool_t *pool) 242{ 243 struct file_baton *fb = file_baton; 244 struct edit_baton *eb = fb->edit_baton; 245 246 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 247 248 return eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton, 249 pool); 250} 251 252static svn_error_t * 253close_directory(void *dir_baton, 254 apr_pool_t *pool) 255{ 256 struct dir_baton *db = dir_baton; 257 struct edit_baton *eb = db->edit_baton; 258 259 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 260 261 return eb->wrapped_editor->close_directory(db->wrapped_dir_baton, pool); 262} 263 264static svn_error_t * 265absent_directory(const char *path, 266 void *dir_baton, 267 apr_pool_t *pool) 268{ 269 struct dir_baton *db = dir_baton; 270 struct edit_baton *eb = db->edit_baton; 271 272 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 273 274 return eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton, 275 pool); 276} 277 278static svn_error_t * 279change_file_prop(void *file_baton, 280 const char *name, 281 const svn_string_t *value, 282 apr_pool_t *pool) 283{ 284 struct file_baton *fb = file_baton; 285 struct edit_baton *eb = fb->edit_baton; 286 287 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 288 289 return eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton, 290 name, value, pool); 291} 292 293static svn_error_t * 294change_dir_prop(void *dir_baton, 295 const char *name, 296 const svn_string_t *value, 297 apr_pool_t *pool) 298{ 299 struct dir_baton *db = dir_baton; 300 struct edit_baton *eb = db->edit_baton; 301 302 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 303 304 return eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton, 305 name, 306 value, 307 pool); 308} 309 310static svn_error_t * 311close_edit(void *edit_baton, 312 apr_pool_t *pool) 313{ 314 struct edit_baton *eb = edit_baton; 315 316 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 317 318 return eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool); 319} 320 321static svn_error_t * 322abort_edit(void *edit_baton, 323 apr_pool_t *pool) 324{ 325 struct edit_baton *eb = edit_baton; 326 327 SVN_ERR(eb->cancel_func(eb->cancel_baton)); 328 329 return eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool); 330} 331 332svn_error_t * 333svn_delta_get_cancellation_editor(svn_cancel_func_t cancel_func, 334 void *cancel_baton, 335 const svn_delta_editor_t *wrapped_editor, 336 void *wrapped_edit_baton, 337 const svn_delta_editor_t **editor, 338 void **edit_baton, 339 apr_pool_t *pool) 340{ 341 if (cancel_func) 342 { 343 svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool); 344 struct edit_baton *eb = apr_palloc(pool, sizeof(*eb)); 345 346 tree_editor->set_target_revision = set_target_revision; 347 tree_editor->open_root = open_root; 348 tree_editor->delete_entry = delete_entry; 349 tree_editor->add_directory = add_directory; 350 tree_editor->open_directory = open_directory; 351 tree_editor->change_dir_prop = change_dir_prop; 352 tree_editor->close_directory = close_directory; 353 tree_editor->absent_directory = absent_directory; 354 tree_editor->add_file = add_file; 355 tree_editor->open_file = open_file; 356 tree_editor->apply_textdelta = apply_textdelta; 357 tree_editor->change_file_prop = change_file_prop; 358 tree_editor->close_file = close_file; 359 tree_editor->absent_file = absent_file; 360 tree_editor->close_edit = close_edit; 361 tree_editor->abort_edit = abort_edit; 362 363 eb->wrapped_editor = wrapped_editor; 364 eb->wrapped_edit_baton = wrapped_edit_baton; 365 eb->cancel_func = cancel_func; 366 eb->cancel_baton = cancel_baton; 367 368 *editor = tree_editor; 369 *edit_baton = eb; 370 } 371 else 372 { 373 *editor = wrapped_editor; 374 *edit_baton = wrapped_edit_baton; 375 } 376 377 return SVN_NO_ERROR; 378} 379