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