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

Generated on Wed Mar 23 12:11:30 2011 for Subversion by  doxygen 1.4.6