Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

svn_delta.h

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

Generated on Thu Aug 25 00:11:39 2005 for Subversion by  doxygen 1.3.9.1