svn commit: r198536 - in user/des/svnsup/src: distill libsvnsup
Dag-Erling Smorgrav
des at FreeBSD.org
Wed Oct 28 09:55:43 UTC 2009
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 <sys/types.h>
+
+#include <stdio.h>
+
+#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 <assert.h>
#include <ctype.h>
#include <stdarg.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#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 <sys/types.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#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);
+}
More information about the svn-src-user
mailing list