* * However! @a offset + @a length may be *beyond* the end of the existing * target data. "Where the heck does the text come from, then?" * If you start at @a offset, and append @a length bytes one at a time, * it'll work out --- you're adding new bytes to the end at the * same rate you're reading them from the middle. Thus, if your * current target text is "abcdefgh", and you get an #svn_txdelta_target * instruction whose @a offset is 6 and whose @a length is 7, * the resulting string is "abcdefghghghghg". This trick is actually * useful in encoding long runs of consecutive characters, long runs * of CR/LF pairs, etc. */ svn_txdelta_target, /** Append the @a length bytes at @a offset in the window's @a new string * to the target. * * It must be the case that 0 <= @a offset < @a offset + * @a length <= length of @a new. Windows MUST use new data in ascending * order with no overlap at the moment; svn_txdelta_to_svndiff() * depends on this. */ svn_txdelta_new }; /** A single text delta instruction. */ typedef struct svn_txdelta_op_t { /** Action code of delta instruction */ enum svn_delta_action action_code; /** Offset of delta, see #svn_delta_action for more details. */ apr_size_t offset; /** Number of bytes of delta, see #svn_delta_action for more details. */ apr_size_t length; } svn_txdelta_op_t; /** An #svn_txdelta_window_t object describes how to reconstruct a * contiguous section of the target string (the "target view") using a * specified contiguous region of the source string (the "source * view"). It contains a series of instructions which assemble the * new target string text by pulling together substrings from: * * - the source view, * * - the previously constructed portion of the target view, * * - a string of new data contained within the window structure * * The source view must always slide forward from one window to the * next; that is, neither the beginning nor the end of the source view * may move to the left as we read from a window stream. This * property allows us to apply deltas to non-seekable source streams * without making a full copy of the source stream. */ typedef struct svn_txdelta_window_t { /** The offset of the source view for this window. */ svn_filesize_t sview_offset; /** The length of the source view for this window. */ apr_size_t sview_len; /** The length of the target view for this window, i.e. the number of * bytes which will be reconstructed by the instruction stream. */ apr_size_t tview_len; /** The number of instructions in this window. */ int num_ops; /** The number of svn_txdelta_source instructions in this window. If * this number is 0, we don't need to read the source in order to * reconstruct the target view. */ int src_ops; /** The instructions for this window. */ const svn_txdelta_op_t *ops; /** New data, for use by any `svn_txdelta_new' instructions. */ const svn_string_t *new_data; } svn_txdelta_window_t; /** * Return a deep copy of @a window, allocated in @a pool. * * @since New in 1.3. */ svn_txdelta_window_t * svn_txdelta_window_dup(const svn_txdelta_window_t *window, apr_pool_t *pool); /** * Compose two delta windows, yielding a third, allocated in @a pool. * * @since New in 1.4 * */ svn_txdelta_window_t * svn_txdelta_compose_windows(const svn_txdelta_window_t *window_A, const svn_txdelta_window_t *window_B, apr_pool_t *pool); /** * Apply the instructions from @a window to a source view @a sbuf to * produce a target view @a tbuf. * * @a sbuf is assumed to have @a window->sview_len bytes of data and * @a tbuf is assumed to have room for @a tlen bytes of output. @a * tlen may be more than @a window->tview_len, so return the actual * number of bytes written. @a sbuf is not touched and may be NULL if * @a window contains no source-copy operations. This is purely a * memory operation; nothing can go wrong as long as we have a valid * window. * * @since New in 1.4 * * @since Since 1.9, @a tbuf may be NULL if @a *tlen is 0. */ void svn_txdelta_apply_instructions(svn_txdelta_window_t *window, const char *sbuf, char *tbuf, apr_size_t *tlen); /** A typedef for functions that consume a series of delta windows, for * use in caller-pushes interfaces. Such functions will typically * apply the delta windows to produce some file, or save the windows * somewhere. At the end of the delta window stream, you must call * this function passing zero for the @a window argument. */ typedef svn_error_t *(*svn_txdelta_window_handler_t)( svn_txdelta_window_t *window, void *baton); /** This function will generate delta windows that turn @a source into * @a target, and pushing these windows into the @a handler window handler * callback (passing @a handler_baton to each invocation). * * If @a checksum is not NULL, then a checksum (of kind @a checksum_kind) * will be computed for the target stream, and placed into *checksum. * * If @a cancel_func is not NULL, then it should refer to a cancellation * function (along with @a cancel_baton). * * Results (the checksum) will be allocated from @a result_pool, and all * temporary allocations will be performed in @a scratch_pool. * * Note: this function replaces the combination of svn_txdelta() and * svn_txdelta_send_txstream(). * * @since New in 1.6. */ svn_error_t * svn_txdelta_run(svn_stream_t *source, svn_stream_t *target, svn_txdelta_window_handler_t handler, void *handler_baton, svn_checksum_kind_t checksum_kind, svn_checksum_t **checksum, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *result_pool, apr_pool_t *scratch_pool); /** A delta stream --- this is the hat from which we pull a series of * svn_txdelta_window_t objects, which, taken in order, describe the * entire target string. This type is defined within libsvn_delta, and * opaque outside that library. */ typedef struct svn_txdelta_stream_t svn_txdelta_stream_t; /** A typedef for a function that will set @a *window to the next * window from a #svn_txdelta_stream_t object. If there are no more * delta windows, NULL will be used. The returned window, if any, * will be allocated in @a pool. @a baton is the baton specified * when the stream was created. * * @since New in 1.4. */ typedef svn_error_t * (*svn_txdelta_next_window_fn_t)(svn_txdelta_window_t **window, void *baton, apr_pool_t *pool); /** A typedef for a function that will return the md5 checksum of the * fulltext deltified by a #svn_txdelta_stream_t object. Will * return NULL if the final null window hasn't yet been returned by * the stream. The returned value will be allocated in the same pool * as the stream. @a baton is the baton specified when the stream was * created. * * @since New in 1.4. */ typedef const unsigned char * (*svn_txdelta_md5_digest_fn_t)(void *baton); /** A typedef for a function that opens an #svn_txdelta_stream_t object, * allocated in @a result_pool. @a baton is provided by the caller. * Any temporary allocations may be performed in @a scratch_pool. * * @since New in 1.10. */ typedef svn_error_t * (*svn_txdelta_stream_open_func_t)(svn_txdelta_stream_t **txdelta_stream, void *baton, apr_pool_t *result_pool, apr_pool_t *scratch_pool); /** Create and return a generic text delta stream with @a baton, @a * next_window and @a md5_digest. Allocate the new stream in @a * pool. * * @since New in 1.4. */ svn_txdelta_stream_t * svn_txdelta_stream_create(void *baton, svn_txdelta_next_window_fn_t next_window, svn_txdelta_md5_digest_fn_t md5_digest, apr_pool_t *pool); /** Set @a *window to a pointer to the next window from the delta stream * @a stream. When we have completely reconstructed the target string, * set @a *window to zero. * * The window will be allocated in @a pool. */ svn_error_t * svn_txdelta_next_window(svn_txdelta_window_t **window, svn_txdelta_stream_t *stream, apr_pool_t *pool); /** Return the md5 digest for the complete fulltext deltified by * @a stream, or @c NULL if @a stream has not yet returned its final * @c NULL window. The digest is allocated in the same memory as @a * STREAM. */ const unsigned char * svn_txdelta_md5_digest(svn_txdelta_stream_t *stream); /** Set @a *stream to a pointer to a delta stream that will turn the byte * string from @a source into the byte stream from @a target. * * @a source and @a target are both readable generic streams. When we call * svn_txdelta_next_window() on @a *stream, it will read from @a source and * @a target to gather as much data as it needs. If @a calculate_checksum * is set, you may call svn_txdelta_md5_digest() to get an MD5 checksum * for @a target. * * Do any necessary allocation in a sub-pool of @a pool. * * @since New in 1.8. */ void svn_txdelta2(svn_txdelta_stream_t **stream, svn_stream_t *source, svn_stream_t *target, svn_boolean_t calculate_checksum, apr_pool_t *pool); /** Similar to svn_txdelta2 but always calculating the target checksum. * * @deprecated Provided for backward compatibility with the 1.7 API. */ SVN_DEPRECATED void svn_txdelta(svn_txdelta_stream_t **stream, svn_stream_t *source, svn_stream_t *target, apr_pool_t *pool); /** * Return a writable stream which, when fed target data, will send * delta windows to @a handler/@a handler_baton which transform the * data in @a source to the target data. As usual, the window handler * will receive a NULL window to signify the end of the window stream. * The stream handler functions will read data from @a source as * necessary. * * @since New in 1.1. */ svn_stream_t * svn_txdelta_target_push(svn_txdelta_window_handler_t handler, void *handler_baton, svn_stream_t *source, apr_pool_t *pool); /** Send the contents of @a string to window-handler @a handler/@a baton. * This is effectively a 'copy' operation, resulting in delta windows that * make the target equivalent to the value of @a string. * * All temporary allocation is performed in @a pool. */ svn_error_t * svn_txdelta_send_string(const svn_string_t *string, svn_txdelta_window_handler_t handler, void *handler_baton, apr_pool_t *pool); /** Send the contents of @a stream to window-handler @a handler/@a baton. * This is effectively a 'copy' operation, resulting in delta windows that * make the target equivalent to the stream. * * If @a digest is non-NULL, populate it with the md5 checksum for the * fulltext that was deltified (@a digest must be at least * @c APR_MD5_DIGESTSIZE bytes long). * * All temporary allocation is performed in @a pool. */ svn_error_t * svn_txdelta_send_stream(svn_stream_t *stream, svn_txdelta_window_handler_t handler, void *handler_baton, unsigned char *digest, apr_pool_t *pool); /** Send the contents of @a txstream to window-handler @a handler/@a baton. * Windows will be extracted from the stream and delivered to the handler. * * All temporary allocation is performed in @a pool. */ svn_error_t * svn_txdelta_send_txstream(svn_txdelta_stream_t *txstream, svn_txdelta_window_handler_t handler, void *handler_baton, apr_pool_t *pool); /** Send the @a contents of length @a len as a txdelta against an empty * source directly to window-handler @a handler/@a handler_baton. * * All temporary allocation is performed in @a pool. * * @since New in 1.8. */ svn_error_t * svn_txdelta_send_contents(const unsigned char *contents, apr_size_t len, svn_txdelta_window_handler_t handler, void *handler_baton, apr_pool_t *pool); /** Prepare to apply a text delta. @a source is a readable generic stream * yielding the source data, @a target is a writable generic stream to * write target data to, and allocation takes place in a sub-pool of * @a pool. On return, @a *handler is set to a window handler function and * @a *handler_baton is set to the value to pass as the @a baton argument to * @a *handler. * * If @a result_digest is non-NULL, it points to APR_MD5_DIGESTSIZE bytes * of storage, and the final call to @a handler populates it with the * MD5 digest of the resulting fulltext. * * If @a error_info is non-NULL, it is inserted parenthetically into * the error string for any error returned by svn_txdelta_apply() or * @a *handler. (It is normally used to provide path information, * since there's nothing else in the delta application's context to * supply a path for error messages.) * * The @a source stream will NOT be closed. The @a target stream will be * closed when the window handler is given a null window to signal the * end of the delta. * * @note To avoid lifetime issues, @a error_info is copied into * @a pool or a subpool thereof. */ void svn_txdelta_apply(svn_stream_t *source, svn_stream_t *target, unsigned char *result_digest, const char *error_info, apr_pool_t *pool, svn_txdelta_window_handler_t *handler, void **handler_baton);