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

Generated on Sat Apr 2 11:52:35 2005 for Subversion by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002