Main Page   Modules   Data Structures   File List   Data Fields  

svn_delta.h

00001 /**
00002  * @copyright
00003  * ====================================================================
00004  * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
00005  *
00006  * This software is licensed as described in the file COPYING, which
00007  * you should have received as part of this distribution.  The terms
00008  * are also available at http://subversion.tigris.org/license-1.html.
00009  * If newer versions of this license are posted there, you may use a
00010  * newer version instead, at your option.
00011  *
00012  * This software consists of voluntary contributions made by many
00013  * individuals.  For exact contribution history, see the revision
00014  * history and logs, available at http://subversion.tigris.org/.
00015  * ====================================================================
00016  * @endcopyright
00017  *
00018  * @file svn_delta.h
00019  * @brief Structures related to delta-parsing
00020  */
00021 
00022 /* ==================================================================== */
00023 
00024 
00025 
00026 #ifndef SVN_DELTA_H
00027 #define SVN_DELTA_H
00028 
00029 #include <apr.h>
00030 #include <apr_pools.h>
00031 
00032 #include "svn_types.h"
00033 #include "svn_string.h"
00034 #include "svn_error.h"
00035 #include "svn_io.h"
00036 
00037 #ifdef __cplusplus
00038 extern "C" {
00039 #endif /* __cplusplus */
00040 
00041 
00042 
00043 /**  Text deltas.
00044  *
00045  * A text delta represents the difference between two strings of
00046  * bytes, the `source' string and the `target' string.  Given a source
00047  * string and a target string, we can compute a text delta; given a
00048  * source string and a delta, we can reconstruct the target string.
00049  * However, note that deltas are not reversible: you cannot always
00050  * reconstruct the source string given the target string and delta.
00051  *
00052  * Since text deltas can be very large, the interface here allows us
00053  * to produce and consume them in pieces.  Each piece, represented by
00054  * an @c svn_txdelta_window_t structure, describes how to produce the
00055  * next section of the target string.
00056  *
00057  * To compute a new text delta:
00058  *
00059  * - We call @c svn_txdelta on the streams we want to compare.  That
00060  *   returns us an @c svn_txdelta_stream_t object.
00061  *
00062  * - We then call @c svn_txdelta_next_window on the stream object
00063  *   repeatedly.  Each call returns a new @c svn_txdelta_window_t
00064  *   object, which describes the next portion of the target string.
00065  *   When @c svn_txdelta_next_window returns zero, we are done building
00066  *   the target string.
00067  *
00068  * @defgroup svn_delta_txt_delta text deltas
00069  * @{
00070  */
00071 
00072 
00073 enum svn_delta_action {
00074     /** Append the @a len bytes at @a offset in the source view to the
00075      * target.
00076      *
00077      * It must be the case that @a 0 <= @a offset < @a offset + 
00078      * @a len <= size of source view.
00079      */
00080     svn_txdelta_source,
00081 
00082     /** Append the @a len bytes at @a offset in the target view, to the
00083      * target.
00084      *
00085      * It must be the case that @a 0 <= @a offset < current position in the 
00086      * target view.
00087      *
00088      * However!  @a offset + @a len may be *beyond* the end of the existing
00089      * target data.  "Where the heck does the text come from, then?"
00090      * If you start at @a offset, and append @a len bytes one at a time,
00091      * it'll work out --- you're adding new bytes to the end at the
00092      * same rate you're reading them from the middle.  Thus, if your
00093      * current target text is "abcdefgh", and you get an @c svn_delta_target
00094      * instruction whose @a offset is @a 6 and whose @a len is @a 7, 
00095      * the resulting string is "abcdefghghghghg".  This trick is actually 
00096      * useful in encoding long runs of consecutive characters, long runs 
00097      * of CR/LF pairs, etc.
00098      */
00099     svn_txdelta_target,
00100 
00101     /** Append the @a len bytes at @a offset in the window's @a new string 
00102      * to the target.
00103      *
00104      * It must be the case that @a 0 <= @a offset < @a offset +
00105      * @a len <= length of @a new.  Windows MUST use new data in ascending
00106      * order with no overlap at the moment; @c svn_txdelta_to_svndiff
00107      * depends on this.
00108      */
00109     svn_txdelta_new
00110 };
00111 
00112 /** A single text delta instruction.  */
00113 typedef struct svn_txdelta_op_t
00114 {
00115   enum svn_delta_action action_code;
00116   apr_size_t offset;
00117   apr_size_t length;
00118 } svn_txdelta_op_t;
00119 
00120 
00121 /** An @c svn_txdelta_window_t object describes how to reconstruct a
00122  * contiguous section of the target string (the "target view") using a
00123  * specified contiguous region of the source string (the "source
00124  * view").  It contains a series of instructions which assemble the
00125  * new target string text by pulling together substrings from:
00126  *
00127  *   - the source view,
00128  *
00129  *   - the previously constructed portion of the target view,
00130  *
00131  *   - a string of new data contained within the window structure
00132  *
00133  * The source view must always slide forward from one window to the
00134  * next; that is, neither the beginning nor the end of the source view
00135  * may move to the left as we read from a window stream.  This
00136  * property allows us to apply deltas to non-seekable source streams
00137  * without making a full copy of the source stream.
00138  */
00139 typedef struct svn_txdelta_window_t
00140 {
00141 
00142   /** The offset of the source view for this window.  */
00143   svn_filesize_t sview_offset;
00144 
00145   /** The length of the source view for this window.  */
00146   apr_size_t sview_len;
00147 
00148   /** The length of the target view for this window, i.e. the number of
00149    * bytes which will be reconstructed by the instruction stream.  */
00150   apr_size_t tview_len;
00151 
00152   /** The number of instructions in this window.  */
00153   int num_ops;
00154 
00155   /** The number of svn_txdelta_source instructions in this window. If
00156    * this number is 0, we don't need to read the source in order to
00157    * reconstruct the target view.
00158    */
00159   int src_ops;
00160 
00161   /** The instructions for this window.  */
00162   const svn_txdelta_op_t *ops;
00163 
00164   /** New data, for use by any `svn_delta_new' instructions.  */
00165   const svn_string_t *new_data;
00166 
00167 } svn_txdelta_window_t;
00168 
00169 
00170 /** A typedef for functions that consume a series of delta windows, for
00171  * use in caller-pushes interfaces.  Such functions will typically
00172  * apply the delta windows to produce some file, or save the windows
00173  * somewhere.  At the end of the delta window stream, you must call
00174  * this function passing zero for the @a window argument.
00175  */
00176 typedef svn_error_t * (*svn_txdelta_window_handler_t)
00177                       (svn_txdelta_window_t *window, void *baton);
00178 
00179 
00180 /** A delta stream --- this is the hat from which we pull a series of
00181  * svn_txdelta_window_t objects, which, taken in order, describe the
00182  * entire target string.  This type is defined within libsvn_delta, and
00183  * opaque outside that library.
00184  */
00185 typedef struct svn_txdelta_stream_t svn_txdelta_stream_t;
00186 
00187 
00188 /** Set @a *window to a pointer to the next window from the delta stream
00189  * @a stream.  When we have completely reconstructed the target string,
00190  * set @a *window to zero.
00191  *
00192  * The window will be allocated in @a pool.
00193  */
00194 svn_error_t *svn_txdelta_next_window (svn_txdelta_window_t **window,
00195                                       svn_txdelta_stream_t *stream,
00196                                       apr_pool_t *pool);
00197 
00198 
00199 /** Return the @a md5 digest for the complete fulltext deltified by
00200  * @a stream, or @c NULL if @a stream has not yet returned its final 
00201  * @c NULL window.  The digest is allocated in the same memory as @a 
00202  * STREAM.
00203  */
00204 const unsigned char *svn_txdelta_md5_digest (svn_txdelta_stream_t *stream);
00205 
00206 /** Set @a *stream to a pointer to a delta stream that will turn the byte
00207  * string from @a source into the byte stream from @a target.
00208  *
00209  * @a source and @a target are both readable generic streams.  When we call
00210  * @c svn_txdelta_next_window on @a *stream, it will read from @a source and
00211  * @a target to gather as much data as it needs.
00212  *
00213  * Do any necessary allocation in a sub-pool of @a pool.
00214  */
00215 void svn_txdelta (svn_txdelta_stream_t **stream,
00216                   svn_stream_t *source,
00217                   svn_stream_t *target,
00218                   apr_pool_t *pool);
00219 
00220 
00221 /** Send the contents of @a string to window-handler @a handler/@a baton. 
00222  * This is effectively a 'copy' operation, resulting in delta windows that 
00223  * make the target equivalent to the value of @a string.
00224  *
00225  * All temporary allocation is performed in @a pool.
00226  */
00227 svn_error_t *svn_txdelta_send_string (const svn_string_t *string,
00228                                       svn_txdelta_window_handler_t handler,
00229                                       void *handler_baton,
00230                                       apr_pool_t *pool);
00231 
00232 /** Send the contents of @a stream to window-handler @a handler/@a baton. 
00233  * This is effectively a 'copy' operation, resulting in delta windows that 
00234  * make the target equivalent to the stream.
00235  *
00236  * If @a digest is non-null, populate it with the md5 checksum for the
00237  * fulltext that was deltified (@a digest must be at least
00238  * @c APR_MD5_DIGESTSIZE bytes long).
00239  *
00240  * All temporary allocation is performed in @a pool.
00241  */
00242 svn_error_t *svn_txdelta_send_stream (svn_stream_t *stream,
00243                                       svn_txdelta_window_handler_t handler,
00244                                       void *handler_baton,
00245                                       unsigned char *digest,
00246                                       apr_pool_t *pool);
00247 
00248 /** Send the contents of @a txstream to window-handler @a handler/@a baton. 
00249  * Windows will be extracted from the stream and delivered to the handler.
00250  *
00251  * All temporary allocation is performed in @a pool.
00252  */
00253 svn_error_t *svn_txdelta_send_txstream (svn_txdelta_stream_t *txstream,
00254                                         svn_txdelta_window_handler_t handler,
00255                                         void *handler_baton,
00256                                         apr_pool_t *pool);
00257 
00258 
00259 /** Prepare to apply a text delta.  @a source is a readable generic stream
00260  * yielding the source data, @a target is a writable generic stream to
00261  * write target data to, and allocation takes place in a sub-pool of
00262  * @a pool.  On return, @a *handler is set to a window handler function and
00263  * @a *handler_baton is set to the value to pass as the @a baton argument to
00264  * @a *handler.
00265  *
00266  * If @a result_digest is non-null, it points to APR_MD5_DIGESTSIZE bytes
00267  * of storage, and the final call to @a handler populates it with the
00268  * MD5 digest of the resulting fulltext.
00269  *
00270  * If @a error_info is non-null, it is inserted parenthetically into
00271  * the error string for any error returned by svn_txdelta_apply() or
00272  * @a *handler.  (It is normally used to provide path information,
00273  * since there's nothing else in the delta application's context to
00274  * supply a path for error messages.)
00275  *
00276  * Note: To avoid lifetime issues, @a error_info is copied into 
00277  * @a pool or a subpool thereof.
00278  */
00279 void svn_txdelta_apply (svn_stream_t *source,
00280                         svn_stream_t *target,
00281                         unsigned char *result_digest,
00282                         const char *error_info,
00283                         apr_pool_t *pool,
00284                         svn_txdelta_window_handler_t *handler,
00285                         void **handler_baton);
00286 
00287 
00288 
00289 /*** Producing and consuming svndiff-format text deltas.  ***/
00290 
00291 /** Prepare to produce an svndiff-format diff from text delta windows.
00292  * @a output is a writable generic stream to write the svndiff data to.
00293  * Allocation takes place in a sub-pool of @a pool.  On return, @a *handler
00294  * is set to a window handler function and @a *handler_baton is set to
00295  * the value to pass as the @a baton argument to @a *handler.
00296  */
00297 void svn_txdelta_to_svndiff (svn_stream_t *output,
00298                              apr_pool_t *pool,
00299                              svn_txdelta_window_handler_t *handler,
00300                              void **handler_baton);
00301 
00302 /** Return a writable generic stream which will parse svndiff-format
00303  * data into a text delta, invoking @a handler with @a handler_baton
00304  * whenever a new window is ready.  If @a error_on_early_close is @c 
00305  * TRUE, attempting to close this stream before it has handled the entire
00306  * svndiff data set will result in @c SVN_ERR_SVNDIFF_UNEXPECTED_END,
00307  * else this error condition will be ignored.
00308  */
00309 svn_stream_t *svn_txdelta_parse_svndiff (svn_txdelta_window_handler_t handler,
00310                                          void *handler_baton,
00311                                          svn_boolean_t error_on_early_close,
00312                                          apr_pool_t *pool);
00313 
00314 /** @} */
00315 
00316 
00317 /** Traversing tree deltas.
00318  *
00319  * In Subversion, we've got various producers and consumers of tree
00320  * deltas.
00321  *
00322  * In processing a `commit' command:
00323  * - The client examines its working copy data, and produces a tree
00324  *   delta describing the changes to be committed.
00325  * - The client networking library consumes that delta, and sends them
00326  *   across the wire as an equivalent series of WebDAV requests.
00327  * - The Apache WebDAV module receives those requests and produces a
00328  *   tree delta --- hopefully equivalent to the one the client
00329  *   produced above.
00330  * - The Subversion server module consumes that delta and commits an
00331  *   appropriate transaction to the filesystem.
00332  *
00333  * In processing an `update' command, the process is reversed:
00334  * - The Subversion server module talks to the filesystem and produces
00335  *   a tree delta describing the changes necessary to bring the
00336  *   client's working copy up to date.
00337  * - The Apache WebDAV module consumes this delta, and assembles a
00338  *   WebDAV reply representing the appropriate changes.
00339  * - The client networking library receives that WebDAV reply, and
00340  *   produces a tree delta --- hopefully equivalent to the one the
00341  *   Subversion server produced above.
00342  * - The working copy library consumes that delta, and makes the
00343  *   appropriate changes to the working copy.
00344  *
00345  * The simplest approach would be to represent tree deltas using the
00346  * obvious data structure.  To do an update, the server would
00347  * construct a delta structure, and the working copy library would
00348  * apply that structure to the working copy; WebDAV's job would simply
00349  * be to get the structure across the net intact.
00350  *
00351  * However, we expect that these deltas will occasionally be too large
00352  * to fit in a typical workstation's swap area.  For example, in
00353  * checking out a 200Mb source tree, the entire source tree is
00354  * represented by a single tree delta.  So it's important to handle
00355  * deltas that are too large to fit in swap all at once.
00356  *
00357  * So instead of representing the tree delta explicitly, we define a
00358  * standard way for a consumer to process each piece of a tree delta
00359  * as soon as the producer creates it.  The @c svn_delta_editor_t
00360  * structure is a set of callback functions to be defined by a delta
00361  * consumer, and invoked by a delta producer.  Each invocation of a
00362  * callback function describes a piece of the delta --- a file's
00363  * contents changing, something being renamed, etc.
00364  *
00365  * @defgroup svn_delta_tree_deltas tree deltas
00366  * @{
00367  */
00368 
00369 /** A structure full of callback functions the delta source will invoke
00370  * as it produces the delta.
00371  *
00372  * <h3>Function Usage</h3>
00373  *
00374  * Here's how to use these functions to express a tree delta.
00375  *
00376  * The delta consumer implements the callback functions described in
00377  * this structure, and the delta producer invokes them.  So the
00378  * caller (producer) is pushing tree delta data at the callee
00379  * (consumer).
00380  *
00381  * At the start of traversal, the consumer provides @a edit_baton, a
00382  * baton global to the entire delta edit.  If there is a target
00383  * revision that needs to be set for this operation, the producer
00384  * should called the @c set_target_revision function at this point.
00385  *
00386  * Next, if there are any tree deltas to express, the producer should
00387  * pass the @a edit_baton to the @c open_root function, to get a baton
00388  * representing root of the tree being edited.
00389  *
00390  * Most of the callbacks work in the obvious way:
00391  *
00392  *     @c delete_entry
00393  *     @c add_file
00394  *     @c add_directory    
00395  *     @c open_file
00396  *     @c open_directory
00397  *
00398  * Each of these takes a directory baton, indicating the directory
00399  * in which the change takes place, and a @a path argument, giving the
00400  * path (relative to the root of the edit) of the file,
00401  * subdirectory, or directory entry to change. Editors will usually
00402  * want to join this relative path with some base stored in the edit
00403  * baton (e.g. a URL, a location in the OS filesystem).
00404  *
00405  * Since every call requires a parent directory baton, including
00406  * add_directory and open_directory, where do we ever get our
00407  * initial directory baton, to get things started?  The @c open_root
00408  * function returns a baton for the top directory of the change.  In
00409  * general, the producer needs to invoke the editor's @c open_root
00410  * function before it can get anything of interest done.
00411  *
00412  * While @c open_root provides a directory baton for the root of
00413  * the tree being changed, the @c add_directory and @c open_directory
00414  * callbacks provide batons for other directories.  Like the
00415  * callbacks above, they take a @a parent_baton and a relative path
00416  * @a path, and then return a new baton for the subdirectory being
00417  * created / modified --- @a child_baton.  The producer can then use
00418  * @a child_baton to make further changes in that subdirectory.
00419  *
00420  * So, if we already have subdirectories named `foo' and `foo/bar',
00421  * then the producer can create a new file named `foo/bar/baz.c' by
00422  * calling:
00423  *
00424  *    - @c open_root () --- yielding a baton @a root for the top directory
00425  *
00426  *    - @c open_directory (@a root, "foo") --- yielding a baton @a f for `foo'
00427  *
00428  *    - @c open_directory (@a f, "foo/bar") --- yielding a baton @a b for 
00429  *    `foo/bar'
00430  *
00431  *    - @c add_file (@a b, "foo/bar/baz.c")
00432  *   
00433  * When the producer is finished making changes to a directory, it
00434  * should call @c close_directory.  This lets the consumer do any
00435  * necessary cleanup, and free the baton's storage.
00436  *
00437  * The @c add_file and @c open_file callbacks each return a baton
00438  * for the file being created or changed.  This baton can then be
00439  * passed to @c apply_textdelta to change the file's contents, or
00440  * @c change_file_prop to change the file's properties.  When the
00441  * producer is finished making changes to a file, it should call
00442  * @c close_file, to let the consumer clean up and free the baton.
00443  *
00444  * The @c add_file and @c add_directory functions each take arguments
00445  * @a copyfrom_path and @a copyfrom_revision.  If @a copyfrom_path is
00446  * non-@c NULL, then @a copyfrom_path and @a copyfrom_revision indicate where
00447  * the file or directory should be copied from (to create the file
00448  * or directory being added).  If @a copyfrom_path is @c NULL, then
00449  * @a copyfrom_revision must be @c SVN_INVALID_REVNUM; it is invalid to
00450  * pass a mix of valid and invalid copyfrom arguments.
00451  *
00452  *
00453  * <h3>Function Call Ordering</h3>
00454  *
00455  * There are six restrictions on the order in which the producer
00456  * may use the batons:
00457  *
00458  * 1. The producer may call @c open_directory, @c add_directory,
00459  *    @c open_file, @c add_file, or @c delete_entry at most once on
00460  *    any given directory entry.
00461  *
00462  * 2. The producer may not close a directory baton until it has
00463  *    closed all batons for its subdirectories.
00464  *
00465  * 3. When a producer calls @c open_directory or @c add_directory,
00466  *    it must specify the most recently opened of the currently open
00467  *    directory batons.  Put another way, the producer cannot have
00468  *    two sibling directory batons open at the same time.
00469  *
00470  * 4. A producer must call @c change_dir_prop on a directory either
00471  *    before opening any of the directory's subdirs or after closing
00472  *    them, but not in the middle.
00473  *
00474  * 5. When the producer calls @c open_file or @c add_file, either:
00475  * 
00476  *    (a) The producer must follow with the changes to the file
00477  *    (@c change_file_prop and/or @c apply_textdelta, as applicable)
00478  *    followed by a @c close_file call, before issuing any other file
00479  *    or directory calls, or
00480  *
00481  *    (b) The producer must follow with a @c change_file_prop call if
00482  *    it is applicable, before issuing any other file or directory
00483  *    calls; later, after all directory batons including the root
00484  *    have been closed, the producer must issue @c apply_textdelta
00485  *    and @c close_file calls.
00486  *
00487  * 6. When the producer calls @c apply_textdelta, it must make all of
00488  *    the window handler calls (including the @c NULL window at the
00489  *    end) before issuing any other @c svn_delta_editor_t calls.
00490  *
00491  * So, the producer needs to use directory and file batons as if it
00492  * is doing a single depth-first traversal of the tree, with the
00493  * exception that the producer may keep file batons open in order to
00494  * make apply_textdelta calls at the end.
00495  *
00496  *
00497  * <h3>Pool Usage</h3>
00498  *
00499  * Many editor functions are invoked multiple times, in a sequence
00500  * determined by the editor "driver". The driver is responsible for
00501  * creating a pool for use on each iteration of the editor function,
00502  * and clearing that pool between each iteration. The driver passes
00503  * the appropriate pool on each function invocation. 
00504  *
00505  * Based on the requirement of calling the editor functions in a
00506  * depth-first style, it is usually customary for the driver to similar
00507  * nest the pools. However, this is only a safety feature to ensure
00508  * that pools associated with deeper items are always cleared when the
00509  * top-level items are also cleared. The interface does not assume, nor
00510  * require, any particular organization of the pools passed to these
00511  * functions. In fact, if "postfix deltas" are used for files, the file
00512  * pools definitely need to live outside the scope of their parent
00513  * directories' pools.
00514  *
00515  * Note that close_directory can be called *before* a file in that
00516  * directory has been closed. That is, the directory's baton is
00517  * closed before the file's baton. The implication is that
00518  * @c apply_textdelta and @c close_file should not refer to a parent
00519  * directory baton UNLESS the editor has taken precautions to
00520  * allocate it in a pool of the appropriate lifetime (the @a dir_pool
00521  * passed to @c open_directory and @c add_directory definitely does not
00522  * have the proper lifetime). In general, it is recommended to simply
00523  * avoid keeping a parent directory baton in a file baton.
00524  *
00525  *
00526  * <h3>Errors</h3>
00527  *
00528  * At least one implementation of the editor interface is
00529  * asynchronous; an error from one operation may be detected some
00530  * number of operations later.  As a result, an editor driver must not
00531  * assume that an error from an editing function resulted from the
00532  * particular operation being detected.  Moreover, once an editing
00533  * function returns an error, the edit is dead; the only further
00534  * operation which may be called on the editor is abort_edit.
00535  */
00536 typedef struct svn_delta_editor_t
00537 {
00538   /** Set the target revision for this edit to @a target_revision.  This
00539    * call, if used, should precede all other editor calls.
00540    */
00541   svn_error_t *(*set_target_revision) (void *edit_baton,
00542                                        svn_revnum_t target_revision,
00543                                        apr_pool_t *pool);
00544 
00545   /** Set @a *root_baton to a baton for the top directory of the change.
00546    * (This is the top of the subtree being changed, not necessarily
00547    * the root of the filesystem.)  Like any other directory baton, the
00548    * producer should call @c close_directory on @a root_baton when they're
00549    * done.  And like other @c open_* calls, the @a base_revision here is
00550    * the current revision of the directory (before getting bumped up
00551    * to the new target revision set with @c set_target_revision).
00552    *
00553    * Allocations for the returned @a root_baton should be performed in
00554    * @a dir_pool. It is also typical to (possibly) save this pool for later
00555    * usage by @c close_directory.
00556    */
00557   svn_error_t *(*open_root) (void *edit_baton,
00558                              svn_revnum_t base_revision,
00559                              apr_pool_t *dir_pool,
00560                              void **root_baton);
00561 
00562 
00563   /** Remove the directory entry named @a path, a child of the directory
00564    * represented by @a parent_baton.  If @a revision is set, it is used as a
00565    * sanity check to ensure that you are removing the revision of @a path
00566    * that you really think you are.
00567    *
00568    * All allocations should be performed in @a pool.
00569    */
00570   svn_error_t *(*delete_entry) (const char *path,
00571                                 svn_revnum_t revision,
00572                                 void *parent_baton,
00573                                 apr_pool_t *pool);
00574 
00575 
00576   /** We are going to add a new subdirectory named @a path.  We will use
00577    * the value this callback stores in @a *child_baton as the
00578    * @a parent_baton for further changes in the new subdirectory.  
00579    *
00580    * If @a copyfrom_path is non-@c NULL, this add has history (i.e., is a
00581    * copy), and the origin of the copy may be recorded as
00582    * @a copyfrom_path under @a copyfrom_revision.
00583    *
00584    * Allocations for the returned @a child_baton should be performed in
00585    * @a dir_pool. It is also typical to (possibly) save this pool for later
00586    * usage by @c close_directory.
00587    */
00588   svn_error_t *(*add_directory) (const char *path,
00589                                  void *parent_baton,
00590                                  const char *copyfrom_path,
00591                                  svn_revnum_t copyfrom_revision,
00592                                  apr_pool_t *dir_pool,
00593                                  void **child_baton);
00594 
00595   /** We are going to make changes in a subdirectory (of the directory
00596    * identified by @a parent_baton). The subdirectory is specified by
00597    * @a path. The callback must store a value in @a *child_baton that 
00598    * should be used as the @a parent_baton for subsequent changes in this
00599    * subdirectory.  If a valid revnum, @a base_revision is the current
00600    * revision of the subdirectory.
00601    *
00602    * Allocations for the returned @a child_baton should be performed in
00603    * @a dir_pool. It is also typical to (possibly) save this pool for later
00604    * usage by @c close_directory.
00605    */
00606   svn_error_t *(*open_directory) (const char *path,
00607                                   void *parent_baton,
00608                                   svn_revnum_t base_revision,
00609                                   apr_pool_t *dir_pool,
00610                                   void **child_baton);
00611 
00612   /** Change the value of a directory's property.
00613    * - @a dir_baton specifies the directory whose property should change.
00614    * - @a name is the name of the property to change.
00615    * - @a value is the new value of the property, or @c NULL if the property
00616    *   should be removed altogether.  
00617    *
00618    * All allocations should be performed in @a pool.
00619    */
00620   svn_error_t *(*change_dir_prop) (void *dir_baton,
00621                                    const char *name,
00622                                    const svn_string_t *value,
00623                                    apr_pool_t *pool);
00624 
00625   /** We are done processing a subdirectory, whose baton is @a dir_baton
00626    * (set by @c add_directory or @c open_directory).  We won't be using
00627    * the baton any more, so whatever resources it refers to may now be
00628    * freed.
00629    */
00630   svn_error_t *(*close_directory) (void *dir_baton,
00631                                    apr_pool_t *pool);
00632 
00633 
00634   /** In the directory represented by @a parent_baton, indicate that
00635    * @a path is present as a subdirectory in the edit source, but
00636    * cannot be conveyed to the edit consumer (perhaps because of
00637    * authorization restrictions).
00638    */
00639   svn_error_t *(*absent_directory) (const char *path,
00640                                     void *parent_baton,
00641                                     apr_pool_t *pool);
00642 
00643   /** We are going to add a new file named @a path.  The callback can
00644    * store a baton for this new file in @a **file_baton; whatever value
00645    * it stores there should be passed through to @c apply_textdelta.
00646    *
00647    * If @a copyfrom_path is non-@c NULL, this add has history (i.e., is a
00648    * copy), and the origin of the copy may be recorded as
00649    * @a copyfrom_path under @a copyfrom_revision.
00650    *
00651    * Allocations for the returned @a file_baton should be performed in
00652    * @a file_pool. It is also typical to save this pool for later usage
00653    * by @c apply_textdelta and possibly @c close_file.
00654    */
00655   svn_error_t *(*add_file) (const char *path,
00656                             void *parent_baton,
00657                             const char *copy_path,
00658                             svn_revnum_t copy_revision,
00659                             apr_pool_t *file_pool,
00660                             void **file_baton);
00661 
00662   /** We are going to make change to a file named @a path, which resides
00663    * in the directory identified by @a parent_baton.
00664    *
00665    * The callback can store a baton for this new file in @a **file_baton;
00666    * whatever value it stores there should be passed through to
00667    * apply_textdelta.  If a valid revnum, @a base_revision is the
00668    * current revision of the file.
00669    *
00670    * Allocations for the returned @a file_baton should be performed in
00671    * @a file_pool. It is also typical to save this pool for later usage
00672    * by @c apply_textdelta and possibly @c close_file.
00673    */
00674   svn_error_t *(*open_file) (const char *path,
00675                              void *parent_baton,
00676                              svn_revnum_t base_revision,
00677                              apr_pool_t *file_pool,
00678                              void **file_baton);
00679 
00680   /** Apply a text delta, yielding the new revision of a file.
00681    *
00682    * @a file_baton indicates the file we're creating or updating, and the
00683    * ancestor file on which it is based; it is the baton set by some
00684    * prior @c add_file or @c open_file callback.
00685    *
00686    * The callback should set @a *handler to a text delta window
00687    * handler; we will then call @a *handler on successive text
00688    * delta windows as we receive them.  The callback should set
00689    * @a *handler_baton to the value we should pass as the @a baton
00690    * argument to @a *handler.
00691    *
00692    * @a base_checksum is the hex MD5 digest for the base text against
00693    * which the delta is being applied; it is ignored if null, and may
00694    * be ignored even if not null.  If it is not ignored, it must match
00695    * the checksum of the base text against which svndiff data is being
00696    * applied; if it does not, apply_textdelta or the @a *handler call
00697    * which detects the mismatch will return the error
00698    * SVN_ERR_CHECKSUM_MISMATCH (if there is no base text, there may
00699    * still be an error if @a base_checksum is neither null nor the hex
00700    * MD5 checksum of the empty string).
00701    */
00702   svn_error_t *(*apply_textdelta) (void *file_baton,
00703                                    const char *base_checksum,
00704                                    apr_pool_t *pool,
00705                                    svn_txdelta_window_handler_t *handler,
00706                                    void **handler_baton);
00707 
00708   /** Change the value of a file's property.
00709    * - @a file_baton specifies the file whose property should change.
00710    * - @a name is the name of the property to change.
00711    * - @a value is the new value of the property, or @c NULL if the property
00712    *   should be removed altogether.
00713    *
00714    * All allocations should be performed in @a pool.
00715    */
00716   svn_error_t *(*change_file_prop) (void *file_baton,
00717                                     const char *name,
00718                                     const svn_string_t *value,
00719                                     apr_pool_t *pool);
00720 
00721   /** We are done processing a file, whose baton is @a file_baton (set by
00722    * @c add_file or @c open_file).  We won't be using the baton any
00723    * more, so whatever resources it refers to may now be freed.
00724    *
00725    * @a text_checksum is the hex MD5 digest for the fulltext that
00726    * resulted from a delta application, see @c apply_textdelta.  The
00727    * checksum is ignored if null.  If not null, it is compared to the
00728    * checksum of the new fulltext, and the error
00729    * SVN_ERR_CHECKSUM_MISMATCH is returned if they do not match.  If
00730    * there is no new fulltext, @a text_checksum is ignored.
00731    */
00732   svn_error_t *(*close_file) (void *file_baton,
00733                               const char *text_checksum,
00734                               apr_pool_t *pool);
00735 
00736   /** In the directory represented by @a parent_baton, indicate that
00737    * @a path is present as a file in the edit source, but cannot be
00738    * conveyed to the edit consumer (perhaps because of authorization
00739    * restrictions).
00740    */
00741   svn_error_t *(*absent_file) (const char *path,
00742                                void *parent_baton,
00743                                apr_pool_t *pool);
00744 
00745   /** All delta processing is done.  Call this, with the @a edit_baton for
00746    * the entire edit.
00747    */
00748   svn_error_t *(*close_edit) (void *edit_baton, 
00749                               apr_pool_t *pool);
00750 
00751   /** The editor-driver has decided to bail out.  Allow the editor to
00752    * gracefully clean up things if it needs to.
00753    */
00754   svn_error_t *(*abort_edit) (void *edit_baton,
00755                               apr_pool_t *pool);
00756 
00757 } svn_delta_editor_t;  
00758 
00759 
00760 /** Return a default delta editor template, allocated in @a pool.
00761  *
00762  * The editor functions in the template do only the most basic
00763  * baton-swapping: each editor function that produces a baton does so
00764  * by copying its incoming baton into the outgoing baton reference.
00765  *
00766  * This editor is not intended to be useful by itself, but is meant to
00767  * be the basis for a useful editor.  After getting a default editor,
00768  * you substitute in your own implementations for the editor functions
00769  * you care about.  The ones you don't care about, you don't have to
00770  * implement -- you can rely on the template's implementation to
00771  * safely do nothing of consequence.
00772  */
00773 svn_delta_editor_t *svn_delta_default_editor (apr_pool_t *pool);
00774 
00775 /** A text-delta window handler which does nothing.
00776  *
00777  * Editors can return this handler from apply_textdelta if they don't
00778  * care about text delta windows.
00779  */
00780 svn_error_t *svn_delta_noop_window_handler (svn_txdelta_window_t *window,
00781                                             void *baton);
00782 
00783 /** Return a cancellation editor that wraps @a wrapped_editor.
00784  *
00785  * The @a editor will call @a cancel_func with @a cancel_baton when each of 
00786  * its functions is called, continuing on to call the corresponding wrapped 
00787  * function if it returns @c SVN_NO_ERROR.
00788  *
00789  * If @a cancel_func is @c NULL, @a *editor is set to @a wrapped_editor and 
00790  * @a *edit_baton is set to @a wrapped_baton.
00791  */
00792 svn_error_t *
00793 svn_delta_get_cancellation_editor (svn_cancel_func_t cancel_func,
00794                                    void *cancel_baton,
00795                                    const svn_delta_editor_t *wrapped_editor,
00796                                    void *wrapped_baton,
00797                                    const svn_delta_editor_t **editor,
00798                                    void **edit_baton,
00799                                    apr_pool_t *pool);
00800 
00801 /** @} */
00802 
00803 
00804 /** Path-based editor drives.
00805  * 
00806  * @defgroup svn_delta_path_delta_drivers path-based delta drivers
00807  * @{
00808  */
00809 
00810 /** Callback function type for svn_delta_path_driver().
00811  *
00812  * The handler of this callback is given the callback baton @a
00813  * callback_baton, @a path, and the @a parent_baton which represents
00814  * path's parent directory as created by the editor passed to
00815  * svn_delta_path_driver().
00816  *
00817  * If @a path represents a directory, the handler must return a @a
00818  * *dir_baton for @a path, generated from the same editor (so that the
00819  * driver can later close that directory).
00820  *
00821  * If, however, @a path represents a file, the handler should NOT
00822  * return any file batons.  It can close any opened or added files
00823  * immediately, or delay that close until the end of the edit when
00824  * svn_delta_path_driver() returns.
00825  *
00826  * Finally, if @a parent_baton is @c NULL, then the root of the edit
00827  * is also one of the paths passed to svn_delta_path_driver().  The
00828  * handler of this callback must call the editor's open_root()
00829  * function and return the top-level root dir baton in @a *dir_baton. 
00830  */
00831 typedef svn_error_t *
00832 (*svn_delta_path_driver_cb_func_t) (void **dir_baton,
00833                                     void *parent_baton,
00834                                     void *callback_baton,
00835                                     const char *path,
00836                                     apr_pool_t *pool);
00837   
00838 
00839 /** Drive @a editor (with its @a edit_baton) in such a way that
00840  * each path in @a paths is traversed in a depth-first fashion.  As
00841  * each path is hit as part of the editor drive, use @a
00842  * callback_func and @a callback_baton to allow the caller to handle
00843  * the portion of the editor drive related to that path.  
00844  *
00845  * Use @a revision as the revision number passed to intermediate
00846  * directory openings.  
00847  *
00848  * Use @a pool for all necessary allocations. 
00849  */
00850 svn_error_t *
00851 svn_delta_path_driver (const svn_delta_editor_t *editor,
00852                        void *edit_baton,
00853                        svn_revnum_t revision,
00854                        apr_array_header_t *paths,
00855                        svn_delta_path_driver_cb_func_t callback_func,
00856                        void *callback_baton,
00857                        apr_pool_t *pool);
00858 
00859 /** @} */
00860 
00861 
00862 #ifdef __cplusplus
00863 }
00864 #endif /* __cplusplus */
00865 
00866 #endif /* SVN_DELTA_H */

Generated on Tue Oct 19 09:49:47 2004 for Subversion by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002