From owner-svn-src-user@FreeBSD.ORG Wed Oct 28 09:55:43 2009 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DB9951065694; Wed, 28 Oct 2009 09:55:42 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CA40F8FC2B; Wed, 28 Oct 2009 09:55:42 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n9S9tgOe057518; Wed, 28 Oct 2009 09:55:42 GMT (envelope-from des@svn.freebsd.org) Received: (from des@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n9S9tgDG057509; Wed, 28 Oct 2009 09:55:42 GMT (envelope-from des@svn.freebsd.org) Message-Id: <200910280955.n9S9tgDG057509@svn.freebsd.org> From: Dag-Erling Smorgrav Date: Wed, 28 Oct 2009 09:55:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r198536 - in user/des/svnsup/src: distill libsvnsup X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Oct 2009 09:55:43 -0000 Author: des Date: Wed Oct 28 09:55:42 2009 New Revision: 198536 URL: http://svn.freebsd.org/changeset/base/198536 Log: Implement most of the delta-generating stuff. Added: user/des/svnsup/src/libsvnsup/svnsup_base64.c (contents, props changed) user/des/svnsup/src/libsvnsup/svnsup_string.c (contents, props changed) Modified: user/des/svnsup/src/distill/distill.c user/des/svnsup/src/distill/editor.c user/des/svnsup/src/distill/txdelta.c user/des/svnsup/src/libsvnsup/Makefile.am user/des/svnsup/src/libsvnsup/svnsup.h user/des/svnsup/src/libsvnsup/svnsup_delta.c Modified: user/des/svnsup/src/distill/distill.c ============================================================================== --- user/des/svnsup/src/distill/distill.c Wed Oct 28 07:05:32 2009 (r198535) +++ user/des/svnsup/src/distill/distill.c Wed Oct 28 09:55:42 2009 (r198536) @@ -50,6 +50,8 @@ distill(const char *url, unsigned long r apr_array_header_t *auth_providers; svn_ra_session_t *ra_session; svn_error_t *error; + svnsup_delta_t sd; + svnsup_err_t err; /* our root pool */ status = apr_pool_create(&pool, NULL); @@ -70,6 +72,10 @@ distill(const char *url, unsigned long r NULL, config, pool); SVNSUP_SVN_ERROR(error, "svn_ra_open3()"); + /* XXX create delta */ + err = svnsup_create_delta(&sd); + SVNSUP_SVNSUP_ERROR(err, "svnsup_delta_create()"); + /* get revision metadata */ error = svn_ra_get_log2(ra_session, NULL, revision, revision, 0, TRUE, TRUE, FALSE, NULL, log_entry_receiver, NULL, pool); @@ -77,9 +83,13 @@ distill(const char *url, unsigned long r /* replay the requested revision */ error = svn_ra_replay(ra_session, revision, revision - 1, TRUE, - &delta_editor, NULL, pool); + &delta_editor, sd, pool); SVNSUP_SVN_ERROR(error, "svn_ra_replay()"); + /* finish off the delta */ + err = svnsup_close_delta(sd); + SVNSUP_SVNSUP_ERROR(err, "svnsup_delta_close()"); + /* clean up */ apr_pool_destroy(pool); return (0); Modified: user/des/svnsup/src/distill/editor.c ============================================================================== --- user/des/svnsup/src/distill/editor.c Wed Oct 28 07:05:32 2009 (r198535) +++ user/des/svnsup/src/distill/editor.c Wed Oct 28 09:55:42 2009 (r198536) @@ -51,11 +51,11 @@ open_root(void *edit_baton, apr_pool_t *dir_pool, void **root_baton) { + svnsup_delta_t sd = (svnsup_delta_t)edit_baton; - (void)edit_baton; (void)dir_pool; SVNSUP_DEBUG("%s(%ld)\n", __func__, (long)base_revision); - *root_baton = (void *)__LINE__; + *root_baton = sd; return (SVN_NO_ERROR); } @@ -65,10 +65,11 @@ delete_entry(const char *path, void *parent_baton, apr_pool_t *pool) { + svnsup_delta_t sd = (svnsup_delta_t)parent_baton; - (void)parent_baton; (void)pool; SVNSUP_DEBUG("%s(%ld, %s)\n", __func__, (long)revision, path); + svnsup_delta_remove(sd, path); return (SVN_NO_ERROR); } @@ -80,12 +81,13 @@ add_directory(const char *path, apr_pool_t *dir_pool, void **child_baton) { + svnsup_delta_t sd = (svnsup_delta_t)parent_baton; - (void)parent_baton; (void)dir_pool; SVNSUP_DEBUG("%s(%s, %s, %ld)\n", __func__, path, copyfrom_path, (long)copyfrom_revision); - *child_baton = (void *)__LINE__; + svnsup_delta_create_directory(sd, path); + *child_baton = sd; /* XXX */ return (SVN_NO_ERROR); } @@ -96,12 +98,12 @@ open_directory(const char *path, apr_pool_t *dir_pool, void **child_baton) { + svnsup_delta_t sd = (svnsup_delta_t)parent_baton; - (void)parent_baton; (void)dir_pool; SVNSUP_DEBUG("%s(%s, %ld)\n", __func__, path, (long)base_revision); - *child_baton = (void *)__LINE__; + *child_baton = sd; /* XXX */ return (SVN_NO_ERROR); } @@ -134,8 +136,9 @@ absent_directory(const char *path, void *parent_baton, apr_pool_t *pool) { + svnsup_delta_t sd = (svnsup_delta_t)parent_baton; - (void)parent_baton; + (void)sd; (void)pool; SVNSUP_DEBUG("%s(%s)\n", __func__, path); return (SVN_NO_ERROR); @@ -149,12 +152,14 @@ add_file(const char *path, apr_pool_t *file_pool, void **file_baton) { + svnsup_delta_t sd = (svnsup_delta_t)parent_baton; + svnsup_delta_file_t sdf; - (void)parent_baton; (void)file_pool; SVNSUP_DEBUG("%s(%s, %s, %ld)\n", __func__, path, copyfrom_path, (long)copyfrom_revision); - *file_baton = (void *)__LINE__; + svnsup_delta_create_file(sd, &sdf, path); + *file_baton = sdf; return (SVN_NO_ERROR); } @@ -165,12 +170,15 @@ open_file(const char *path, apr_pool_t *file_pool, void **file_baton) { + svnsup_delta_t sd = (svnsup_delta_t)parent_baton; + svnsup_delta_file_t sdf; - (void)parent_baton; + (void)sd; (void)file_pool; SVNSUP_DEBUG("%s(%s, %ld)\n", __func__, path, (long)base_revision); - *file_baton = (void *)__LINE__; + svnsup_delta_open_file(sd, &sdf, path); + *file_baton = sdf; return (SVN_NO_ERROR); } @@ -181,12 +189,15 @@ apply_textdelta(void *file_baton, svn_txdelta_window_handler_t *handler, void **handler_baton) { + svnsup_delta_file_t sdf = (svnsup_delta_file_t)file_baton; - (void)file_baton; + (void)sdf; (void)pool; SVNSUP_DEBUG("%s(%s)\n", __func__, base_checksum); + if (base_checksum) + svnsup_delta_file_checksum(sdf, base_checksum); *handler = txdelta_window_handler; - *handler_baton = (void *)__LINE__; + *handler_baton = file_baton; return (SVN_NO_ERROR); } @@ -196,8 +207,9 @@ change_file_prop(void *file_baton, const svn_string_t *value, apr_pool_t *pool) { + svnsup_delta_file_t sdf = (svnsup_delta_file_t)file_baton; - (void)file_baton; + (void)sdf; (void)pool; SVNSUP_DEBUG("%s(%s, %s)\n", __func__, name, value->data); return (SVN_NO_ERROR); @@ -208,10 +220,11 @@ close_file(void *file_baton, const char *text_checksum, apr_pool_t *pool) { + svnsup_delta_file_t sdf = (svnsup_delta_file_t)file_baton; - (void)file_baton; (void)pool; SVNSUP_DEBUG("%s(%s)\n", __func__, text_checksum); + svnsup_delta_close_file(sdf, text_checksum); return (SVN_NO_ERROR); } @@ -220,8 +233,9 @@ absent_file(const char *path, void *parent_baton, apr_pool_t *pool) { + svnsup_delta_t sd = (svnsup_delta_t)parent_baton; - (void)parent_baton; + (void)sd; (void)pool; SVNSUP_DEBUG("%s(%s)\n", __func__, path); return (SVN_NO_ERROR); Modified: user/des/svnsup/src/distill/txdelta.c ============================================================================== --- user/des/svnsup/src/distill/txdelta.c Wed Oct 28 07:05:32 2009 (r198535) +++ user/des/svnsup/src/distill/txdelta.c Wed Oct 28 09:55:42 2009 (r198536) @@ -35,49 +35,42 @@ #include "distill.h" +// XXX documentation + error handling svn_error_t * txdelta_window_handler(svn_txdelta_window_t *window, void *baton) { + svnsup_delta_file_t sdf = (svnsup_delta_file_t)baton; const svn_txdelta_op_t *op; - int i; + unsigned int txtid = 0; + int i, ret; - (void)baton; SVNSUP_DEBUG("%s()\n", __func__); - if (!debug) + if (window == NULL) return (SVN_NO_ERROR); - if (window == NULL) { - fprintf(stderr, "end of delta\n"); - return (SVN_NO_ERROR); - } else { - fprintf(stderr, "delta\n"); + if (window->new_data != NULL && window->new_data->len > 0) { + SVNSUP_DEBUG("%lu bytes of data\n", + (unsigned long)window->new_data->len); + ret = svnsup_delta_file_text(sdf, window->new_data->data, + window->new_data->len, &txtid); + SVNSUP_SVNSUP_ERROR(ret, "svnsup_delta_file_text()"); } - fprintf(stderr, " src off: %ld\n", (long)window->sview_offset); - fprintf(stderr, " src len: %ld\n", (long)window->sview_len); - fprintf(stderr, " tgt len: %ld\n", (long)window->tview_len); - fprintf(stderr, " ops: %d (%d src)\n", window->num_ops, window->src_ops); for (i = 0, op = window->ops; i < window->num_ops; ++i, ++op) { - fprintf(stderr, " op #%d: ", i); switch (op->action_code) { case svn_txdelta_source: - fprintf(stderr, "src %ld:%ld\n", - (long)op->offset, (long)op->length); + svnsup_delta_file_copy(sdf, op->offset, op->length); break; case svn_txdelta_target: - fprintf(stderr, "tgt %ld:%ld\n", - (long)op->offset, (long)op->length); + svnsup_delta_file_repeat(sdf, op->offset, op->length); break; case svn_txdelta_new: - fprintf(stderr, "new %ld:%ld\n", - (long)op->offset, (long)op->length); - if (verbose) - fprintf(stderr, "%.*s\n", (int)op->length, - window->new_data->data + op->offset); + svnsup_delta_file_insert(sdf, txtid, op->offset, + op->length); break; default: - fprintf(stderr, "???\n"); + SVNSUP_ASSERT(0, "invalid window operation"); break; } } Modified: user/des/svnsup/src/libsvnsup/Makefile.am ============================================================================== --- user/des/svnsup/src/libsvnsup/Makefile.am Wed Oct 28 07:05:32 2009 (r198535) +++ user/des/svnsup/src/libsvnsup/Makefile.am Wed Oct 28 09:55:42 2009 (r198536) @@ -3,7 +3,9 @@ lib_LIBRARIES = libsvnsup.a libsvnsup_a_SOURCES = \ - svnsup_delta.c + svnsup_base64.c \ + svnsup_delta.c \ + svnsup_string.c noinst_HEADERS = \ svnsup.h Modified: user/des/svnsup/src/libsvnsup/svnsup.h ============================================================================== --- user/des/svnsup/src/libsvnsup/svnsup.h Wed Oct 28 07:05:32 2009 (r198535) +++ user/des/svnsup/src/libsvnsup/svnsup.h Wed Oct 28 09:55:42 2009 (r198536) @@ -37,11 +37,52 @@ typedef enum svnsup_err { SVNSUP_ERR_MAX, } svnsup_err_t; +/* + * svnsup_delta.c + */ typedef struct svnsup_delta *svnsup_delta_t; +typedef struct svnsup_delta_file *svnsup_delta_file_t; -int svnsup_delta_create(svnsup_delta_t *); -int svnsup_delta_close(svnsup_delta_t); +int svnsup_create_delta(svnsup_delta_t *); +int svnsup_close_delta(svnsup_delta_t); int svnsup_delta_comment(svnsup_delta_t, const char *, ...); +int svnsup_delta_meta(svnsup_delta_t, const char *, const char *, ...); +int svnsup_delta_create_directory(svnsup_delta_t, const char *); +int svnsup_delta_remove(svnsup_delta_t, const char *); +int svnsup_delta_text(svnsup_delta_t, const char *, size_t, + unsigned int *); + +int svnsup_delta_create_file(svnsup_delta_t, svnsup_delta_file_t *, + const char *); +int svnsup_delta_open_file(svnsup_delta_t, svnsup_delta_file_t *, + const char *); +int svnsup_delta_file_checksum(svnsup_delta_file_t, const char *); +int svnsup_delta_file_text(svnsup_delta_file_t, const char *, size_t, + unsigned int *); +int svnsup_delta_file_copy(svnsup_delta_file_t, off_t, size_t); +int svnsup_delta_file_repeat(svnsup_delta_file_t, off_t, size_t); +int svnsup_delta_file_insert(svnsup_delta_file_t, unsigned int, off_t, size_t); +int svnsup_delta_close_file(svnsup_delta_file_t, const char *); + +/* + * svnsup_string.c + */ +int svnsup_string_is_safe(const char *); +int svnsup_buf_is_safe(const char *, size_t); +char *svnsup_string_encode(const char *); +char *svnsup_buf_encode(const char *, size_t); + +#ifdef FOPEN_MAX /* defined by stdio.h, cf. IEEE 1003.1 */ +int svnsup_string_fencode(FILE *, const char *); +int svnsup_buf_fencode(FILE *, const char *, size_t); +#endif + +/* + * svnsup_base64.c + */ +#ifdef FOPEN_MAX /* defined by stdio.h, cf. IEEE 1003.1 */ +int svnsup_base64_fencode(FILE *, const unsigned char *, size_t); +#endif #endif Added: user/des/svnsup/src/libsvnsup/svnsup_base64.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/des/svnsup/src/libsvnsup/svnsup_base64.c Wed Oct 28 09:55:42 2009 (r198536) @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2009 Dag-Erling Coïdan Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +#include "svnsup.h" + +static const char b64t[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/" + "="; + +int +svnsup_base64_fencode(FILE *f, const unsigned char *buf, size_t size) +{ + int count = 0; +#if 0 + int width = 0; +#endif + + while (size >= 3) { + putc(b64t[buf[0] >> 2], f); + putc(b64t[(buf[0] << 4 | buf[1] >> 4) & 0x3f], f); + putc(b64t[(buf[1] << 2 | buf[2] >> 6) & 0x3f], f); + putc(b64t[buf[2] & 0x3f], f); + count += 4; + buf += 3; + size -= 3; +#if 0 + if ((width += 3) == 64 && size > 0) { + putc('\n', f); + ++count; + width = 0; + } +#endif + } + if (size > 0) { + putc(b64t[buf[0] >> 2], f); + if (size > 1) { + putc(b64t[(buf[0] << 4 | buf[1] >> 4) & 0x3f], f); + putc(b64t[(buf[1] << 2) & 0x3f], f); + } else { + putc(b64t[(buf[0] << 4) & 0x3f], f); + putc('=', f); + } + putc('=', f); + count += 4; + } + return (count); +} Modified: user/des/svnsup/src/libsvnsup/svnsup_delta.c ============================================================================== --- user/des/svnsup/src/libsvnsup/svnsup_delta.c Wed Oct 28 07:05:32 2009 (r198535) +++ user/des/svnsup/src/libsvnsup/svnsup_delta.c Wed Oct 28 09:55:42 2009 (r198536) @@ -31,20 +31,61 @@ #include "config.h" #endif +#include #include #include +#include #include #include +#include #include "svnsup.h" +// XXX missing I/O error handling + struct svnsup_delta { FILE *f; - int started:1; + struct svnsup_delta_file *sdf; + unsigned int ntxt; +}; + +struct svnsup_delta_file { + struct svnsup_delta *sd; + char *fn; + int create:1; + int checksum:1; }; +static svnsup_delta_file_t +svnsup_delta_file_alloc(svnsup_delta_t sd, const char *fn) +{ + svnsup_delta_file_t sdf; + + if ((sdf = calloc(1, sizeof *sdf)) == NULL) { + return (NULL); + } else if ((sdf->fn = strdup(fn)) == NULL) { + free(sdf); + return (NULL); + } + sdf->sd = sd; + sd->sdf = sdf; + return (sdf); +} + +void +svnsup_delta_file_free(svnsup_delta_file_t sdf) +{ + + sdf->sd->sdf = NULL; + free(sdf->fn); + free(sdf); +} + +/* + * Create an svnsup delta. + */ int -svnsup_delta_create(svnsup_delta_t *sdp) +svnsup_create_delta(svnsup_delta_t *sdp) { svnsup_delta_t sd; @@ -55,14 +96,21 @@ svnsup_delta_create(svnsup_delta_t *sdp) return (SVNSUP_ERR_NONE); } +/* + * Close an svnsup delta. + */ int -svnsup_delta_close(svnsup_delta_t sd) +svnsup_close_delta(svnsup_delta_t sd) { + assert(sd->sdf == NULL); free(sd); return (SVNSUP_ERR_NONE); } +/* + * Comment + */ int svnsup_delta_comment(svnsup_delta_t sd, const char *fmt, ...) { @@ -77,15 +125,226 @@ svnsup_delta_comment(svnsup_delta_t sd, return (SVNSUP_ERR_MEMORY); p = commentbuf; while (*p != '\0') { - fputs("# ", sd->f); + fprintf(sd->f, "# "); while (*p != '\0' && *p != '\n') { - putc(isprint(*p) ? *p : ' ', sd->f); + fprintf(sd->f, "%c", isprint(*p) ? *p : ' '); ++p; } - putc('\n', sd->f); + fprintf(sd->f, "\n"); if (*p == '\n') ++p; } free(commentbuf); return (SVNSUP_ERR_NONE); } + +/* + * Metadata + */ +int +svnsup_delta_meta(svnsup_delta_t sd, const char *key, const char *fmt, ...) +{ + + (void)sd; + (void)key; + (void)fmt; + return (SVNSUP_ERR_NONE); +} + +/* + * Create a directory + */ +int +svnsup_delta_create_directory(svnsup_delta_t sd, const char *dn) +{ + + assert(sd != NULL); + assert(dn != NULL && *dn != '\0'); + assert(sd->sdf == NULL); + fprintf(sd->f, "@mkdir "); + svnsup_string_fencode(sd->f, dn); + fprintf(sd->f, "\n"); + return (SVNSUP_ERR_NONE); +} + +/* + * Remove a file or directory + */ +int +svnsup_delta_remove(svnsup_delta_t sd, const char *fn) +{ + + assert(sd != NULL); + assert(fn != NULL && *fn != '\0'); + assert(sd->sdf == NULL); + fprintf(sd->f, "@remove "); + svnsup_string_fencode(sd->f, fn); + fprintf(sd->f, "\n"); + return (SVNSUP_ERR_NONE); +} + +/* + * Text to be used in later edits + */ +int +svnsup_delta_text(svnsup_delta_t sd, const char *src, size_t len, + unsigned int *txtid) +{ + + assert(sd != NULL); + assert(src != NULL); + assert(len > 0); + assert(txtid != NULL); + *txtid = sd->ntxt++; + fprintf(sd->f, "@text %u ", *txtid); + svnsup_buf_fencode(sd->f, src, len); + fprintf(sd->f, "\n"); + return (SVNSUP_ERR_NONE); +} + +/* + * Create a file and start working on it + */ +int +svnsup_delta_create_file(svnsup_delta_t sd, svnsup_delta_file_t *sdfp, + const char *fn) +{ + svnsup_delta_file_t sdf; + + assert(sd != NULL); + assert(sd->sdf == NULL); + assert(sdfp != NULL); + assert(fn != NULL && *fn != '\0'); + if ((sdf = svnsup_delta_file_alloc(sd, fn)) == NULL) + return (SVNSUP_ERR_MEMORY); + sdf->create = 1; + *sdfp = sdf; + fprintf(sd->f, "@create "); + svnsup_string_fencode(sd->f, fn); + fprintf(sd->f, "\n"); + return (SVNSUP_ERR_NONE); +} + +/* + * Start working on the specified file + */ +int +svnsup_delta_open_file(svnsup_delta_t sd, svnsup_delta_file_t *sdfp, + const char *fn) +{ + svnsup_delta_file_t sdf; + + assert(sd != NULL); + assert(sd->sdf == NULL); + assert(sdfp != NULL); + assert(fn != NULL && *fn != '\0'); + if ((sdf = svnsup_delta_file_alloc(sd, fn)) == NULL) + return (SVNSUP_ERR_MEMORY); + *sdfp = sdf; + return (SVNSUP_ERR_NONE); +} + +/* + * Checksum of the original file + */ +int +svnsup_delta_file_checksum(svnsup_delta_file_t sdf, const char *md5) +{ + + assert(sdf != NULL); + assert(sdf->sd != NULL); + assert(sdf->sd->sdf == sdf); + assert(sdf->fn != NULL); + assert(!sdf->create); + assert(*sdf->fn != '\0'); + assert(md5 != NULL && *md5 != '\0'); + fprintf(sdf->sd->f, "@open "); + svnsup_string_fencode(sdf->sd->f, sdf->fn); + fprintf(sdf->sd->f, " md5 "); + svnsup_string_fencode(sdf->sd->f, md5); + fprintf(sdf->sd->f, "\n"); + sdf->checksum = 1; + return (SVNSUP_ERR_NONE); +} + +/* + * Shortcut to svnsup_delta_text() + */ +int +svnsup_delta_file_text(svnsup_delta_file_t sdf, const char *src, size_t len, + unsigned int *txtid) +{ + + return (svnsup_delta_text(sdf->sd, src, len, txtid)); +} + +/* + * Copy text from the original file to the new file + */ +int +svnsup_delta_file_copy(svnsup_delta_file_t sdf, off_t off, size_t size) +{ + + assert(sdf != NULL); + assert(sdf->sd != NULL); + assert(sdf->sd->sdf == sdf); + assert(sdf->create || sdf->checksum); + assert(size > 0); + fprintf(sdf->sd->f, "@copy %ju %zu\n", (uintmax_t)off, size); + return (SVNSUP_ERR_NONE); +} + +/* + * Repeat text in the new file + */ +int +svnsup_delta_file_repeat(svnsup_delta_file_t sdf, off_t off, size_t size) +{ + + assert(sdf != NULL); + assert(sdf->sd != NULL); + assert(sdf->sd->sdf == sdf); + assert(sdf->create || sdf->checksum); + assert(size > 0); + fprintf(sdf->sd->f, "@repeat %ju %zu\n", (uintmax_t)off, size); + return (SVNSUP_ERR_NONE); +} + +/* + * Insert text into the new file + */ +int +svnsup_delta_file_insert(svnsup_delta_file_t sdf, unsigned int txtid, + off_t off, size_t size) +{ + + assert(sdf != NULL); + assert(sdf->sd != NULL); + assert(sdf->sd->sdf == sdf); + assert(sdf->create || sdf->checksum); + assert(txtid < sdf->sd->ntxt); + assert(size > 0); + fprintf(sdf->sd->f, "@insert %u %ju %zu\n", txtid, (uintmax_t)off, size); + return (SVNSUP_ERR_NONE); +} + +/* + * Stop working on the specified file + */ +int +svnsup_delta_close_file(svnsup_delta_file_t sdf, const char *md5) +{ + + assert(sdf != NULL); + assert(sdf->sd != NULL); + assert(sdf->sd->sdf == sdf); + assert(sdf->create || sdf->checksum); + assert(md5 != NULL && *md5 != '\0'); + fprintf(sdf->sd->f, "@close "); + svnsup_string_fencode(sdf->sd->f, sdf->fn); + fprintf(sdf->sd->f, " md5 "); + svnsup_string_fencode(sdf->sd->f, md5); + fprintf(sdf->sd->f, "\n"); + svnsup_delta_file_free(sdf); + return (SVNSUP_ERR_NONE); +} Added: user/des/svnsup/src/libsvnsup/svnsup_string.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/des/svnsup/src/libsvnsup/svnsup_string.c Wed Oct 28 09:55:42 2009 (r198536) @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2009 Dag-Erling Coïdan Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include +#include + +#include "svnsup.h" + +/* + * Safe to send as is + */ +int +svnsup_string_is_safe(const char *str) +{ + + while (*str != '\0') { + if (!isprint(*str) || isspace(*str)) + return (0); + ++str; + } + return (1); +} + +/* + * Safe to send as is + */ +int +svnsup_buf_is_safe(const char *buf, size_t size) +{ + + while (size > 0) { + if (!isprint(*buf) || isspace(*buf)) + return (0); + ++buf; + --size; + } + return (1); +} + +char * +svnsup_string_encode(const char *str) +{ + + assert(0); + (void)str; + return (NULL); +} + +char * +svnsup_buf_encode(const char *buf, size_t size) +{ + + assert(0); + (void)buf; + (void)size; + return (NULL); +} + +int +svnsup_string_fencode(FILE *f, const char *str) +{ + + return (svnsup_buf_fencode(f, str, strlen(str))); +} + +int +svnsup_buf_fencode(FILE *f, const char *buf, size_t size) +{ + int len; + + if (svnsup_buf_is_safe(buf, size)) + return (fprintf(f, "%zu[%.*s]", size, (int)size, buf)); + len = fprintf(f, "%zu{", size); + len += svnsup_base64_fencode(f, (const unsigned char *)buf, size); + len += fprintf(f, "}"); + return (len); +}