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
26 struct 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
35 struct dir_baton
36 {
37 void *edit_baton;
38 void *wrapped_dir_baton;
39 };
40
41 struct file_baton
42 {
43 void *edit_baton;
44 void *wrapped_file_baton;
45 };
46
47 static svn_error_t *
set_target_revision(void * edit_baton,svn_revnum_t target_revision,apr_pool_t * pool)48 set_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
61 static svn_error_t *
open_root(void * edit_baton,svn_revnum_t base_revision,apr_pool_t * pool,void ** root_baton)62 open_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
84 static svn_error_t *
delete_entry(const char * path,svn_revnum_t base_revision,void * parent_baton,apr_pool_t * pool)85 delete_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
101 static svn_error_t *
add_directory(const char * path,void * parent_baton,const char * copyfrom_path,svn_revnum_t copyfrom_revision,apr_pool_t * pool,void ** child_baton)102 add_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
128 static svn_error_t *
open_directory(const char * path,void * parent_baton,svn_revnum_t base_revision,apr_pool_t * pool,void ** child_baton)129 open_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
153 static svn_error_t *
add_file(const char * path,void * parent_baton,const char * copyfrom_path,svn_revnum_t copyfrom_revision,apr_pool_t * pool,void ** file_baton)154 add_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
180 static svn_error_t *
open_file(const char * path,void * parent_baton,svn_revnum_t base_revision,apr_pool_t * pool,void ** file_baton)181 open_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
205 static svn_error_t *
apply_textdelta(void * file_baton,const char * base_checksum,apr_pool_t * pool,svn_txdelta_window_handler_t * handler,void ** handler_baton)206 apply_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
224 static svn_error_t *
apply_textdelta_stream(const svn_delta_editor_t * editor,void * file_baton,const char * base_checksum,svn_txdelta_stream_open_func_t open_func,void * open_baton,apr_pool_t * scratch_pool)225 apply_textdelta_stream(const svn_delta_editor_t *editor,
226 void *file_baton,
227 const char *base_checksum,
228 svn_txdelta_stream_open_func_t open_func,
229 void *open_baton,
230 apr_pool_t *scratch_pool)
231 {
232 struct file_baton *fb = file_baton;
233 struct edit_baton *eb = fb->edit_baton;
234
235 SVN_ERR(eb->cancel_func(eb->cancel_baton));
236
237 return eb->wrapped_editor->apply_textdelta_stream(eb->wrapped_editor,
238 fb->wrapped_file_baton,
239 base_checksum,
240 open_func, open_baton,
241 scratch_pool);
242 }
243
244 static svn_error_t *
close_file(void * file_baton,const char * text_checksum,apr_pool_t * pool)245 close_file(void *file_baton,
246 const char *text_checksum,
247 apr_pool_t *pool)
248 {
249 struct file_baton *fb = file_baton;
250 struct edit_baton *eb = fb->edit_baton;
251
252 SVN_ERR(eb->cancel_func(eb->cancel_baton));
253
254 return eb->wrapped_editor->close_file(fb->wrapped_file_baton,
255 text_checksum, pool);
256 }
257
258 static svn_error_t *
absent_file(const char * path,void * file_baton,apr_pool_t * pool)259 absent_file(const char *path,
260 void *file_baton,
261 apr_pool_t *pool)
262 {
263 struct file_baton *fb = file_baton;
264 struct edit_baton *eb = fb->edit_baton;
265
266 SVN_ERR(eb->cancel_func(eb->cancel_baton));
267
268 return eb->wrapped_editor->absent_file(path, fb->wrapped_file_baton,
269 pool);
270 }
271
272 static svn_error_t *
close_directory(void * dir_baton,apr_pool_t * pool)273 close_directory(void *dir_baton,
274 apr_pool_t *pool)
275 {
276 struct dir_baton *db = dir_baton;
277 struct edit_baton *eb = db->edit_baton;
278
279 SVN_ERR(eb->cancel_func(eb->cancel_baton));
280
281 return eb->wrapped_editor->close_directory(db->wrapped_dir_baton, pool);
282 }
283
284 static svn_error_t *
absent_directory(const char * path,void * dir_baton,apr_pool_t * pool)285 absent_directory(const char *path,
286 void *dir_baton,
287 apr_pool_t *pool)
288 {
289 struct dir_baton *db = dir_baton;
290 struct edit_baton *eb = db->edit_baton;
291
292 SVN_ERR(eb->cancel_func(eb->cancel_baton));
293
294 return eb->wrapped_editor->absent_directory(path, db->wrapped_dir_baton,
295 pool);
296 }
297
298 static svn_error_t *
change_file_prop(void * file_baton,const char * name,const svn_string_t * value,apr_pool_t * pool)299 change_file_prop(void *file_baton,
300 const char *name,
301 const svn_string_t *value,
302 apr_pool_t *pool)
303 {
304 struct file_baton *fb = file_baton;
305 struct edit_baton *eb = fb->edit_baton;
306
307 SVN_ERR(eb->cancel_func(eb->cancel_baton));
308
309 return eb->wrapped_editor->change_file_prop(fb->wrapped_file_baton,
310 name, value, pool);
311 }
312
313 static svn_error_t *
change_dir_prop(void * dir_baton,const char * name,const svn_string_t * value,apr_pool_t * pool)314 change_dir_prop(void *dir_baton,
315 const char *name,
316 const svn_string_t *value,
317 apr_pool_t *pool)
318 {
319 struct dir_baton *db = dir_baton;
320 struct edit_baton *eb = db->edit_baton;
321
322 SVN_ERR(eb->cancel_func(eb->cancel_baton));
323
324 return eb->wrapped_editor->change_dir_prop(db->wrapped_dir_baton,
325 name,
326 value,
327 pool);
328 }
329
330 static svn_error_t *
close_edit(void * edit_baton,apr_pool_t * pool)331 close_edit(void *edit_baton,
332 apr_pool_t *pool)
333 {
334 struct edit_baton *eb = edit_baton;
335
336 SVN_ERR(eb->cancel_func(eb->cancel_baton));
337
338 return eb->wrapped_editor->close_edit(eb->wrapped_edit_baton, pool);
339 }
340
341 static svn_error_t *
abort_edit(void * edit_baton,apr_pool_t * pool)342 abort_edit(void *edit_baton,
343 apr_pool_t *pool)
344 {
345 struct edit_baton *eb = edit_baton;
346
347 SVN_ERR(eb->cancel_func(eb->cancel_baton));
348
349 return eb->wrapped_editor->abort_edit(eb->wrapped_edit_baton, pool);
350 }
351
352 svn_error_t *
svn_delta_get_cancellation_editor(svn_cancel_func_t cancel_func,void * cancel_baton,const svn_delta_editor_t * wrapped_editor,void * wrapped_edit_baton,const svn_delta_editor_t ** editor,void ** edit_baton,apr_pool_t * pool)353 svn_delta_get_cancellation_editor(svn_cancel_func_t cancel_func,
354 void *cancel_baton,
355 const svn_delta_editor_t *wrapped_editor,
356 void *wrapped_edit_baton,
357 const svn_delta_editor_t **editor,
358 void **edit_baton,
359 apr_pool_t *pool)
360 {
361 if (cancel_func)
362 {
363 svn_delta_editor_t *tree_editor = svn_delta_default_editor(pool);
364 struct edit_baton *eb = apr_palloc(pool, sizeof(*eb));
365
366 tree_editor->set_target_revision = set_target_revision;
367 tree_editor->open_root = open_root;
368 tree_editor->delete_entry = delete_entry;
369 tree_editor->add_directory = add_directory;
370 tree_editor->open_directory = open_directory;
371 tree_editor->change_dir_prop = change_dir_prop;
372 tree_editor->close_directory = close_directory;
373 tree_editor->absent_directory = absent_directory;
374 tree_editor->add_file = add_file;
375 tree_editor->open_file = open_file;
376 tree_editor->apply_textdelta = apply_textdelta;
377 tree_editor->apply_textdelta_stream = apply_textdelta_stream;
378 tree_editor->change_file_prop = change_file_prop;
379 tree_editor->close_file = close_file;
380 tree_editor->absent_file = absent_file;
381 tree_editor->close_edit = close_edit;
382 tree_editor->abort_edit = abort_edit;
383
384 eb->wrapped_editor = wrapped_editor;
385 eb->wrapped_edit_baton = wrapped_edit_baton;
386 eb->cancel_func = cancel_func;
387 eb->cancel_baton = cancel_baton;
388
389 *editor = tree_editor;
390 *edit_baton = eb;
391 }
392 else
393 {
394 *editor = wrapped_editor;
395 *edit_baton = wrapped_edit_baton;
396 }
397
398 return SVN_NO_ERROR;
399 }
400