Subversion
|
A structure full of callback functions the delta source will invoke as it produces the delta. More...
#include <svn_delta.h>
Data Fields | |
svn_error_t *(* | set_target_revision )(void *edit_baton, svn_revnum_t target_revision, apr_pool_t *scratch_pool) |
Set the target revision for this edit to target_revision. | |
svn_error_t *(* | open_root )(void *edit_baton, svn_revnum_t base_revision, apr_pool_t *result_pool, void **root_baton) |
Set *root_baton to a baton for the top directory of the change. | |
svn_error_t *(* | delete_entry )(const char *path, svn_revnum_t revision, void *parent_baton, apr_pool_t *scratch_pool) |
Remove the directory entry named path, a child of the directory represented by parent_baton. | |
svn_error_t *(* | add_directory )(const char *path, void *parent_baton, const char *copyfrom_path, svn_revnum_t copyfrom_revision, apr_pool_t *result_pool, void **child_baton) |
We are going to add a new subdirectory named path. | |
svn_error_t *(* | open_directory )(const char *path, void *parent_baton, svn_revnum_t base_revision, apr_pool_t *result_pool, void **child_baton) |
We are going to make changes in a subdirectory (of the directory identified by parent_baton). | |
svn_error_t *(* | change_dir_prop )(void *dir_baton, const char *name, const svn_string_t *value, apr_pool_t *scratch_pool) |
Change the value of a directory's property. | |
svn_error_t *(* | close_directory )(void *dir_baton, apr_pool_t *scratch_pool) |
We are done processing a subdirectory, whose baton is dir_baton (set by add_directory or open_directory ). | |
svn_error_t *(* | absent_directory )(const char *path, void *parent_baton, apr_pool_t *scratch_pool) |
In the directory represented by parent_baton, indicate that path is present as a subdirectory in the edit source, but cannot be conveyed to the edit consumer (perhaps because of authorization restrictions). | |
svn_error_t *(* | add_file )(const char *path, void *parent_baton, const char *copyfrom_path, svn_revnum_t copyfrom_revision, apr_pool_t *result_pool, void **file_baton) |
We are going to add a new file named path. | |
svn_error_t *(* | open_file )(const char *path, void *parent_baton, svn_revnum_t base_revision, apr_pool_t *result_pool, void **file_baton) |
We are going to make change to a file named path, which resides in the directory identified by parent_baton. | |
svn_error_t *(* | apply_textdelta )(void *file_baton, const char *base_checksum, apr_pool_t *result_pool, svn_txdelta_window_handler_t *handler, void **handler_baton) |
Apply a text delta, yielding the new revision of a file. | |
svn_error_t *(* | change_file_prop )(void *file_baton, const char *name, const svn_string_t *value, apr_pool_t *scratch_pool) |
Change the value of a file's property. | |
svn_error_t *(* | close_file )(void *file_baton, const char *text_checksum, apr_pool_t *scratch_pool) |
We are done processing a file, whose baton is file_baton (set by add_file or open_file ). | |
svn_error_t *(* | absent_file )(const char *path, void *parent_baton, apr_pool_t *scratch_pool) |
In the directory represented by parent_baton, indicate that path is present as a file in the edit source, but cannot be conveyed to the edit consumer (perhaps because of authorization restrictions). | |
svn_error_t *(* | close_edit )(void *edit_baton, apr_pool_t *scratch_pool) |
All delta processing is done. | |
svn_error_t *(* | abort_edit )(void *edit_baton, apr_pool_t *scratch_pool) |
The editor-driver has decided to bail out. |
A structure full of callback functions the delta source will invoke as it produces the delta.
Here's how to use these functions to express a tree delta.
The delta consumer implements the callback functions described in this structure, and the delta producer invokes them. So the caller (producer) is pushing tree delta data at the callee (consumer).
At the start of traversal, the consumer provides edit_baton, a baton global to the entire delta edit. If there is a target revision that needs to be set for this operation, the producer should call the set_target_revision
function at this point.
Next, if there are any tree deltas to express, the producer should pass the edit_baton to the open_root
function, to get a baton representing root of the tree being edited.
Most of the callbacks work in the obvious way:
delete_entry
add_file
add_directory
open_file
open_directory
Each of these takes a directory baton, indicating the directory in which the change takes place, and a path argument, giving the path (relative to the root of the edit) of the file, subdirectory, or directory entry to change. Editors will usually want to join this relative path with some base stored in the edit baton (e.g. a URL, a location in the OS filesystem).
Since every call requires a parent directory baton, including add_directory
and open_directory
, where do we ever get our initial directory baton, to get things started? The open_root
function returns a baton for the top directory of the change. In general, the producer needs to invoke the editor's open_root
function before it can get anything of interest done.
While open_root
provides a directory baton for the root of the tree being changed, the add_directory
and open_directory
callbacks provide batons for other directories. Like the callbacks above, they take a parent_baton and a relative path path, and then return a new baton for the subdirectory being created / modified --- child_baton. The producer can then use child_baton to make further changes in that subdirectory.
So, if we already have subdirectories named `foo' and `foo/bar', then the producer can create a new file named `foo/bar/baz.c' by calling:
open_root
() --- yielding a baton root for the top directoryopen_directory
(root, "foo") --- yielding a baton f for `foo'open_directory
(f, "foo/bar") --- yielding a baton b for `foo/bar'add_file
(b, "foo/bar/baz.c")When the producer is finished making changes to a directory, it should call close_directory
. This lets the consumer do any necessary cleanup, and free the baton's storage.
The add_file
and open_file
callbacks each return a baton for the file being created or changed. This baton can then be passed to apply_textdelta
to change the file's contents, or change_file_prop
to change the file's properties. When the producer is finished making changes to a file, it should call close_file
, to let the consumer clean up and free the baton.
The add_file
and add_directory
functions each take arguments copyfrom_path and copyfrom_revision. If copyfrom_path is non-NULL
, then copyfrom_path and copyfrom_revision indicate where the file or directory should be copied from (to create the file or directory being added). In that case, copyfrom_path must be either a path relative to the root of the edit, or a URI from the repository being edited. If copyfrom_path is NULL
, then copyfrom_revision must be SVN_INVALID_REVNUM; it is invalid to pass a mix of valid and invalid copyfrom arguments.
There are six restrictions on the order in which the producer may use the batons:
1. The producer may call open_directory
, add_directory
, open_file
, add_file
at most once on any given directory entry. delete_entry
may be called at most once on any given directory entry and may later be followed by add_directory
or add_file
on the same directory entry. delete_entry
may not be called on any directory entry after open_directory
, add_directory
, open_file
or add_file
has been called on that directory entry.
2. The producer may not close a directory baton until it has closed all batons for its subdirectories.
3. When a producer calls open_directory
or add_directory
, it must specify the most recently opened of the currently open directory batons. Put another way, the producer cannot have two sibling directory batons open at the same time.
4. A producer must call change_dir_prop
on a directory either before opening any of the directory's subdirs or after closing them, but not in the middle.
5. When the producer calls open_file
or add_file
, either:
(a) The producer must follow with any changes to the file (change_file_prop
and/or apply_textdelta
, as applicable), followed by a close_file
call, before issuing any other file or directory calls, or
(b) The producer must follow with a change_file_prop
call if it is applicable, before issuing any other file or directory calls; later, after all directory batons including the root have been closed, the producer must issue apply_textdelta
and close_file
calls.
6. When the producer calls apply_textdelta
, it must make all of the window handler calls (including the NULL
window at the end) before issuing any other svn_delta_editor_t calls.
So, the producer needs to use directory and file batons as if it is doing a single depth-first traversal of the tree, with the exception that the producer may keep file batons open in order to make apply_textdelta
calls at the end.
Many editor functions are invoked multiple times, in a sequence determined by the editor "driver". The driver is responsible for creating a pool for use on each iteration of the editor function, and clearing that pool between each iteration. The driver passes the appropriate pool on each function invocation.
Based on the requirement of calling the editor functions in a depth-first style, it is usually customary for the driver to similarly nest the pools. However, this is only a safety feature to ensure that pools associated with deeper items are always cleared when the top-level items are also cleared. The interface does not assume, nor require, any particular organization of the pools passed to these functions. In fact, if "postfix deltas" are used for files, the file pools definitely need to live outside the scope of their parent directories' pools.
Note that close_directory can be called *before* a file in that directory has been closed. That is, the directory's baton is closed before the file's baton. The implication is that apply_textdelta
and close_file
should not refer to a parent directory baton UNLESS the editor has taken precautions to allocate it in a pool of the appropriate lifetime (the dir_pool passed to open_directory
and add_directory
definitely does not have the proper lifetime). In general, it is recommended to simply avoid keeping a parent directory baton in a file baton.
At least one implementation of the editor interface is asynchronous; an error from one operation may be detected some number of operations later. As a result, an editor driver must not assume that an error from an editing function resulted from the particular operation being detected. Moreover, once an editing function returns an error, the edit is dead; the only further operation which may be called on the editor is abort_edit.
Definition at line 795 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::abort_edit)(void *edit_baton, apr_pool_t *scratch_pool) |
The editor-driver has decided to bail out.
Allow the editor to gracefully clean up things if it needs to.
Any temporary allocations may be performed in scratch_pool.
Definition at line 1060 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::absent_directory)(const char *path, void *parent_baton, apr_pool_t *scratch_pool) |
In the directory represented by parent_baton, indicate that path is present as a subdirectory in the edit source, but cannot be conveyed to the edit consumer (perhaps because of authorization restrictions).
Any temporary allocations may be performed in scratch_pool.
Definition at line 920 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::absent_file)(const char *path, void *parent_baton, apr_pool_t *scratch_pool) |
In the directory represented by parent_baton, indicate that path is present as a file in the edit source, but cannot be conveyed to the edit consumer (perhaps because of authorization restrictions).
Any temporary allocations may be performed in scratch_pool.
Definition at line 1043 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::add_directory)(const char *path, void *parent_baton, const char *copyfrom_path, svn_revnum_t copyfrom_revision, apr_pool_t *result_pool, void **child_baton) |
We are going to add a new subdirectory named path.
We will use the value this callback stores in *child_baton as the parent_baton for further changes in the new subdirectory.
If copyfrom_path is non-NULL
, this add has history (i.e., is a copy), and the origin of the copy may be recorded as copyfrom_path under copyfrom_revision.
Allocations for the returned child_baton should be performed in result_pool. It is also typical to (possibly) save this pool for later usage by close_directory
.
Definition at line 862 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::add_file)(const char *path, void *parent_baton, const char *copyfrom_path, svn_revnum_t copyfrom_revision, apr_pool_t *result_pool, void **file_baton) |
We are going to add a new file named path.
The callback can store a baton for this new file in **file_baton; whatever value it stores there should be passed through to apply_textdelta
.
If copyfrom_path is non-NULL
, this add has history (i.e., is a copy), and the origin of the copy may be recorded as copyfrom_path under copyfrom_revision.
Allocations for the returned file_baton should be performed in result_pool. It is also typical to save this pool for later usage by apply_textdelta
and possibly close_file
.
Definition at line 946 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::apply_textdelta)(void *file_baton, const char *base_checksum, apr_pool_t *result_pool, svn_txdelta_window_handler_t *handler, void **handler_baton) |
Apply a text delta, yielding the new revision of a file.
file_baton indicates the file we're creating or updating, and the ancestor file on which it is based; it is the baton set by some prior add_file
or open_file
callback.
The callback should set *handler to a text delta window handler; we will then call *handler on successive text delta windows as we receive them. The callback should set *handler_baton to the value we should pass as the baton argument to *handler. These values should be allocated within result_pool.
base_checksum is the hex MD5 digest for the base text against which the delta is being applied; it is ignored if NULL, and may be ignored even if not NULL. If it is not ignored, it must match the checksum of the base text against which svndiff data is being applied; if it does not, apply_textdelta
or the *handler call which detects the mismatch will return the error SVN_ERR_CHECKSUM_MISMATCH (if there is no base text, there may still be an error if base_checksum is neither NULL nor the hex MD5 checksum of the empty string).
Definition at line 997 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::change_dir_prop)(void *dir_baton, const char *name, const svn_string_t *value, apr_pool_t *scratch_pool) |
Change the value of a directory's property.
NULL
if the property should be removed altogether.The callback is guaranteed to be called exactly once for each property whose value differs between the start and the end of the edit.
Any temporary allocations may be performed in scratch_pool.
Definition at line 897 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::change_file_prop)(void *file_baton, const char *name, const svn_string_t *value, apr_pool_t *scratch_pool) |
Change the value of a file's property.
NULL
if the property should be removed altogether.The callback is guaranteed to be called exactly once for each property whose value differs between the start and the end of the edit.
Any temporary allocations may be performed in scratch_pool.
Definition at line 1014 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::close_directory)(void *dir_baton, apr_pool_t *scratch_pool) |
We are done processing a subdirectory, whose baton is dir_baton (set by add_directory
or open_directory
).
We won't be using the baton any more, so whatever resources it refers to may now be freed.
Any temporary allocations may be performed in scratch_pool.
Definition at line 909 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::close_edit)(void *edit_baton, apr_pool_t *scratch_pool) |
All delta processing is done.
Call this, with the edit_baton for the entire edit.
Any temporary allocations may be performed in scratch_pool.
Definition at line 1052 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::close_file)(void *file_baton, const char *text_checksum, apr_pool_t *scratch_pool) |
We are done processing a file, whose baton is file_baton (set by add_file
or open_file
).
We won't be using the baton any more, so whatever resources it refers to may now be freed.
text_checksum is the hex MD5 digest for the fulltext that resulted from a delta application, see apply_textdelta
. The checksum is ignored if NULL. If not null, it is compared to the checksum of the new fulltext, and the error SVN_ERR_CHECKSUM_MISMATCH is returned if they do not match. If there is no new fulltext, text_checksum is ignored.
Any temporary allocations may be performed in scratch_pool.
Definition at line 1032 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::delete_entry)(const char *path, svn_revnum_t revision, void *parent_baton, apr_pool_t *scratch_pool) |
Remove the directory entry named path, a child of the directory represented by parent_baton.
If revision is a valid revision number, it is used as a sanity check to ensure that you are really removing the revision of path that you think you are.
Any temporary allocations may be performed in scratch_pool.
Definition at line 844 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::open_directory)(const char *path, void *parent_baton, svn_revnum_t base_revision, apr_pool_t *result_pool, void **child_baton) |
We are going to make changes in a subdirectory (of the directory identified by parent_baton).
The subdirectory is specified by path. The callback must store a value in *child_baton that should be used as the parent_baton for subsequent changes in this subdirectory. If a valid revnum, base_revision is the current revision of the subdirectory.
Allocations for the returned child_baton should be performed in result_pool. It is also typical to (possibly) save this pool for later usage by close_directory
.
Definition at line 880 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::open_file)(const char *path, void *parent_baton, svn_revnum_t base_revision, apr_pool_t *result_pool, void **file_baton) |
We are going to make change to a file named path, which resides in the directory identified by parent_baton.
The callback can store a baton for this new file in **file_baton; whatever value it stores there should be passed through to apply_textdelta
. If a valid revnum, base_revision is the current revision of the file.
Allocations for the returned file_baton should be performed in result_pool. It is also typical to save this pool for later usage by apply_textdelta
and possibly close_file
.
Definition at line 968 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::open_root)(void *edit_baton, svn_revnum_t base_revision, apr_pool_t *result_pool, void **root_baton) |
Set *root_baton to a baton for the top directory of the change.
(This is the top of the subtree being changed, not necessarily the root of the filesystem.) As with any other directory baton, the producer should call close_directory
on root_baton when done. And as with other open_*
calls, the base_revision here is the current revision of the directory (before getting bumped up to the new target revision set with set_target_revision
).
Allocations for the returned root_baton should be performed in result_pool. It is also typical to (possibly) save this pool for later usage by close_directory
.
Definition at line 823 of file svn_delta.h.
svn_error_t*(* svn_delta_editor_t::set_target_revision)(void *edit_baton, svn_revnum_t target_revision, apr_pool_t *scratch_pool) |
Set the target revision for this edit to target_revision.
This call, if used, should precede all other editor calls.
Any temporary allocations may be performed in scratch_pool.
Definition at line 807 of file svn_delta.h.