summaryrefslogtreecommitdiff
path: root/subversion/libsvn_ra_svn/marshal.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_ra_svn/marshal.c')
-rw-r--r--subversion/libsvn_ra_svn/marshal.c1553
1 files changed, 1365 insertions, 188 deletions
diff --git a/subversion/libsvn_ra_svn/marshal.c b/subversion/libsvn_ra_svn/marshal.c
index 588ccb4..7cf483f 100644
--- a/subversion/libsvn_ra_svn/marshal.c
+++ b/subversion/libsvn_ra_svn/marshal.c
@@ -32,6 +32,7 @@
#include <apr_lib.h>
#include <apr_strings.h>
+#include "svn_hash.h"
#include "svn_types.h"
#include "svn_string.h"
#include "svn_error.h"
@@ -39,11 +40,13 @@
#include "svn_ra_svn.h"
#include "svn_private_config.h"
#include "svn_ctype.h"
+#include "svn_time.h"
#include "ra_svn.h"
#include "private/svn_string_private.h"
#include "private/svn_dep_compat.h"
+#include "private/svn_error_private.h"
#define svn_iswhitespace(c) ((c) == ' ' || (c) == '\n')
@@ -53,15 +56,27 @@
#define SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD (0x100000)
+/* Return the APR socket timeout to be used for the connection depending
+ * on whether there is a blockage handler or zero copy has been activated. */
+static apr_interval_time_t
+get_timeout(svn_ra_svn_conn_t *conn)
+{
+ return conn->block_handler ? 0 : -1;
+}
+
/* --- CONNECTION INITIALIZATION --- */
-svn_ra_svn_conn_t *svn_ra_svn_create_conn2(apr_socket_t *sock,
+svn_ra_svn_conn_t *svn_ra_svn_create_conn3(apr_socket_t *sock,
apr_file_t *in_file,
apr_file_t *out_file,
int compression_level,
+ apr_size_t zero_copy_limit,
+ apr_size_t error_check_interval,
apr_pool_t *pool)
{
- svn_ra_svn_conn_t *conn = apr_palloc(pool, sizeof(*conn));
+ svn_ra_svn_conn_t *conn;
+ void *mem = apr_palloc(pool, sizeof(*conn) + SVN_RA_SVN__PAGE_SIZE);
+ conn = (void*)APR_ALIGN((apr_uintptr_t)mem, SVN_RA_SVN__PAGE_SIZE);
assert((sock && !in_file && !out_file) || (!sock && in_file && out_file));
#ifdef SVN_HAVE_SASL
@@ -72,10 +87,14 @@ svn_ra_svn_conn_t *svn_ra_svn_create_conn2(apr_socket_t *sock,
conn->read_ptr = conn->read_buf;
conn->read_end = conn->read_buf;
conn->write_pos = 0;
+ conn->written_since_error_check = 0;
+ conn->error_check_interval = error_check_interval;
+ conn->may_check_for_error = error_check_interval == 0;
conn->block_handler = NULL;
conn->block_baton = NULL;
conn->capabilities = apr_hash_make(pool);
conn->compression_level = compression_level;
+ conn->zero_copy_limit = zero_copy_limit;
conn->pool = pool;
if (sock != NULL)
@@ -85,6 +104,7 @@ svn_ra_svn_conn_t *svn_ra_svn_create_conn2(apr_socket_t *sock,
if (!(apr_socket_addr_get(&sa, APR_REMOTE, sock) == APR_SUCCESS
&& apr_sockaddr_ip_get(&conn->remote_ip, sa) == APR_SUCCESS))
conn->remote_ip = NULL;
+ svn_ra_svn__stream_timeout(conn->stream, get_timeout(conn));
}
else
{
@@ -95,14 +115,25 @@ svn_ra_svn_conn_t *svn_ra_svn_create_conn2(apr_socket_t *sock,
return conn;
}
+svn_ra_svn_conn_t *svn_ra_svn_create_conn2(apr_socket_t *sock,
+ apr_file_t *in_file,
+ apr_file_t *out_file,
+ int compression_level,
+ apr_pool_t *pool)
+{
+ return svn_ra_svn_create_conn3(sock, in_file, out_file,
+ compression_level, 0, 0, pool);
+}
+
/* backward-compatible implementation using the default compression level */
svn_ra_svn_conn_t *svn_ra_svn_create_conn(apr_socket_t *sock,
apr_file_t *in_file,
apr_file_t *out_file,
apr_pool_t *pool)
{
- return svn_ra_svn_create_conn2(sock, in_file, out_file,
- SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, pool);
+ return svn_ra_svn_create_conn3(sock, in_file, out_file,
+ SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, 0, 0,
+ pool);
}
svn_error_t *svn_ra_svn_set_capabilities(svn_ra_svn_conn_t *conn,
@@ -119,16 +150,23 @@ svn_error_t *svn_ra_svn_set_capabilities(svn_ra_svn_conn_t *conn,
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("Capability entry is not a word"));
word = apr_pstrdup(conn->pool, item->u.word);
- apr_hash_set(conn->capabilities, word, APR_HASH_KEY_STRING, word);
+ svn_hash_sets(conn->capabilities, word, word);
}
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_ra_svn__set_shim_callbacks(svn_ra_svn_conn_t *conn,
+ svn_delta_shim_callbacks_t *shim_callbacks)
+{
+ conn->shim_callbacks = shim_callbacks;
+ return SVN_NO_ERROR;
+}
+
svn_boolean_t svn_ra_svn_has_capability(svn_ra_svn_conn_t *conn,
const char *capability)
{
- return (apr_hash_get(conn->capabilities, capability,
- APR_HASH_KEY_STRING) != NULL);
+ return (svn_hash_gets(conn->capabilities, capability) != NULL);
}
int
@@ -137,6 +175,12 @@ svn_ra_svn_compression_level(svn_ra_svn_conn_t *conn)
return conn->compression_level;
}
+apr_size_t
+svn_ra_svn_zero_copy_limit(svn_ra_svn_conn_t *conn)
+{
+ return conn->zero_copy_limit;
+}
+
const char *svn_ra_svn_conn_remote_host(svn_ra_svn_conn_t *conn)
{
return conn->remote_ip;
@@ -147,11 +191,9 @@ svn_ra_svn__set_block_handler(svn_ra_svn_conn_t *conn,
ra_svn_block_handler_t handler,
void *baton)
{
- apr_interval_time_t interval = (handler) ? 0 : -1;
-
conn->block_handler = handler;
conn->block_baton = baton;
- svn_ra_svn__stream_timeout(conn->stream, interval);
+ svn_ra_svn__stream_timeout(conn->stream, get_timeout(conn));
}
svn_boolean_t svn_ra_svn__input_waiting(svn_ra_svn_conn_t *conn,
@@ -162,20 +204,6 @@ svn_boolean_t svn_ra_svn__input_waiting(svn_ra_svn_conn_t *conn,
/* --- WRITE BUFFER MANAGEMENT --- */
-/* Write bytes into the write buffer until either the write buffer is
- * full or we reach END. */
-static const char *writebuf_push(svn_ra_svn_conn_t *conn, const char *data,
- const char *end)
-{
- apr_ssize_t buflen, copylen;
-
- buflen = sizeof(conn->write_buf) - conn->write_pos;
- copylen = (buflen < end - data) ? buflen : end - data;
- memcpy(conn->write_buf + conn->write_pos, data, copylen);
- conn->write_pos += copylen;
- return data + copylen;
-}
-
/* Write data to socket or output file as appropriate. */
static svn_error_t *writebuf_output(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
const char *data, apr_size_t len)
@@ -214,6 +242,10 @@ static svn_error_t *writebuf_output(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
}
}
+ conn->written_since_error_check += len;
+ conn->may_check_for_error
+ = conn->written_since_error_check >= conn->error_check_interval;
+
if (subpool)
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
@@ -222,7 +254,7 @@ static svn_error_t *writebuf_output(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
/* Write data from the write buffer out to the socket. */
static svn_error_t *writebuf_flush(svn_ra_svn_conn_t *conn, apr_pool_t *pool)
{
- int write_pos = conn->write_pos;
+ apr_size_t write_pos = conn->write_pos;
/* Clear conn->write_pos first in case the block handler does a read. */
conn->write_pos = 0;
@@ -233,35 +265,56 @@ static svn_error_t *writebuf_flush(svn_ra_svn_conn_t *conn, apr_pool_t *pool)
static svn_error_t *writebuf_write(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
const char *data, apr_size_t len)
{
- const char *end = data + len;
-
- if (conn->write_pos > 0 && conn->write_pos + len > sizeof(conn->write_buf))
+ /* data >= 8k is sent immediately */
+ if (len >= sizeof(conn->write_buf) / 2)
{
- /* Fill and then empty the write buffer. */
- data = writebuf_push(conn, data, end);
- SVN_ERR(writebuf_flush(conn, pool));
+ if (conn->write_pos > 0)
+ SVN_ERR(writebuf_flush(conn, pool));
+
+ return writebuf_output(conn, pool, data, len);
}
- if (end - data > (apr_ssize_t)sizeof(conn->write_buf))
- SVN_ERR(writebuf_output(conn, pool, data, end - data));
- else
- writebuf_push(conn, data, end);
+ /* ensure room for the data to add */
+ if (conn->write_pos + len > sizeof(conn->write_buf))
+ SVN_ERR(writebuf_flush(conn, pool));
+
+ /* buffer the new data block as well */
+ memcpy(conn->write_buf + conn->write_pos, data, len);
+ conn->write_pos += len;
+
return SVN_NO_ERROR;
}
-static svn_error_t *writebuf_printf(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- const char *fmt, ...)
- __attribute__ ((format(printf, 3, 4)));
-static svn_error_t *writebuf_printf(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- const char *fmt, ...)
+static svn_error_t *
+writebuf_write_short_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
+ const char *data, apr_size_t len)
{
- va_list ap;
- char *str;
+ apr_size_t left = sizeof(conn->write_buf) - conn->write_pos;
+ if (len <= left)
+ {
+ memcpy(conn->write_buf + conn->write_pos, data, len);
+ conn->write_pos += len;
+ return SVN_NO_ERROR;
+ }
+ else
+ return writebuf_write(conn, pool, data, len);
+}
- va_start(ap, fmt);
- str = apr_pvsprintf(pool, fmt, ap);
- va_end(ap);
- return writebuf_write(conn, pool, str, strlen(str));
+static APR_INLINE svn_error_t *
+writebuf_writechar(svn_ra_svn_conn_t *conn, apr_pool_t *pool, char data)
+{
+ if (conn->write_pos < sizeof(conn->write_buf))
+ {
+ conn->write_buf[conn->write_pos] = data;
+ conn->write_pos++;
+
+ return SVN_NO_ERROR;
+ }
+ else
+ {
+ char temp = data;
+ return writebuf_write(conn, pool, &temp, 1);
+ }
}
/* --- READ BUFFER MANAGEMENT --- */
@@ -305,6 +358,31 @@ static svn_error_t *readbuf_input(svn_ra_svn_conn_t *conn, char *data,
return SVN_NO_ERROR;
}
+/* Treat the next LEN input bytes from CONN as "read" */
+static svn_error_t *readbuf_skip(svn_ra_svn_conn_t *conn, apr_uint64_t len)
+{
+ do
+ {
+ apr_size_t buflen = conn->read_end - conn->read_ptr;
+ apr_size_t copylen = (buflen < len) ? buflen : (apr_size_t)len;
+ conn->read_ptr += copylen;
+ len -= copylen;
+ if (len == 0)
+ break;
+
+ buflen = sizeof(conn->read_buf);
+ SVN_ERR(svn_ra_svn__stream_read(conn->stream, conn->read_buf, &buflen));
+ if (buflen == 0)
+ return svn_error_create(SVN_ERR_RA_SVN_CONNECTION_CLOSED, NULL, NULL);
+
+ conn->read_end = conn->read_buf + buflen;
+ conn->read_ptr = conn->read_buf;
+ }
+ while (len > 0);
+
+ return SVN_NO_ERROR;
+}
+
/* Read data from the socket into the read buffer, which must be empty. */
static svn_error_t *readbuf_fill(svn_ra_svn_conn_t *conn, apr_pool_t *pool)
{
@@ -408,35 +486,85 @@ static svn_error_t *readbuf_skip_leading_garbage(svn_ra_svn_conn_t *conn,
/* --- WRITING DATA ITEMS --- */
-svn_error_t *svn_ra_svn_write_number(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- apr_uint64_t number)
+static svn_error_t *write_number(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
+ apr_uint64_t number, char follow)
+{
+ apr_size_t written;
+
+ /* SVN_INT64_BUFFER_SIZE includes space for a terminating NUL that
+ * svn__ui64toa will always append. */
+ if (conn->write_pos + SVN_INT64_BUFFER_SIZE >= sizeof(conn->write_buf))
+ SVN_ERR(writebuf_flush(conn, pool));
+
+ written = svn__ui64toa(conn->write_buf + conn->write_pos, number);
+ conn->write_buf[conn->write_pos + written] = follow;
+ conn->write_pos += written + 1;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_number(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ apr_uint64_t number)
{
- return writebuf_printf(conn, pool, "%" APR_UINT64_T_FMT " ", number);
+ return write_number(conn, pool, number, ' ');
}
-svn_error_t *svn_ra_svn_write_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- const svn_string_t *str)
+svn_error_t *
+svn_ra_svn__write_string(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const svn_string_t *str)
{
- SVN_ERR(writebuf_printf(conn, pool, "%" APR_SIZE_T_FMT ":", str->len));
+ if (str->len < 10)
+ {
+ SVN_ERR(writebuf_writechar(conn, pool, (char)(str->len + '0')));
+ SVN_ERR(writebuf_writechar(conn, pool, ':'));
+ }
+ else
+ SVN_ERR(write_number(conn, pool, str->len, ':'));
+
SVN_ERR(writebuf_write(conn, pool, str->data, str->len));
- SVN_ERR(writebuf_write(conn, pool, " ", 1));
+ SVN_ERR(writebuf_writechar(conn, pool, ' '));
return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_write_cstring(svn_ra_svn_conn_t *conn,
- apr_pool_t *pool, const char *s)
+svn_error_t *
+svn_ra_svn__write_cstring(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *s)
{
- return writebuf_printf(conn, pool, "%" APR_SIZE_T_FMT ":%s ", strlen(s), s);
+ apr_size_t len = strlen(s);
+
+ if (len < 10)
+ {
+ SVN_ERR(writebuf_writechar(conn, pool, (char)(len + '0')));
+ SVN_ERR(writebuf_writechar(conn, pool, ':'));
+ }
+ else
+ SVN_ERR(write_number(conn, pool, len, ':'));
+
+ SVN_ERR(writebuf_write(conn, pool, s, len));
+ SVN_ERR(writebuf_writechar(conn, pool, ' '));
+
+ return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_write_word(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- const char *word)
+svn_error_t *
+svn_ra_svn__write_word(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *word)
{
- return writebuf_printf(conn, pool, "%s ", word);
+ SVN_ERR(writebuf_write_short_string(conn, pool, word, strlen(word)));
+ SVN_ERR(writebuf_writechar(conn, pool, ' '));
+
+ return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_write_proplist(svn_ra_svn_conn_t *conn,
- apr_pool_t *pool, apr_hash_t *props)
+svn_error_t *
+svn_ra_svn__write_proplist(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ apr_hash_t *props)
{
apr_pool_t *iterpool;
apr_hash_index_t *hi;
@@ -454,8 +582,8 @@ svn_error_t *svn_ra_svn_write_proplist(svn_ra_svn_conn_t *conn,
apr_hash_this(hi, &key, NULL, &val);
propname = key;
propval = val;
- SVN_ERR(svn_ra_svn_write_tuple(conn, iterpool, "cs",
- propname, propval));
+ SVN_ERR(svn_ra_svn__write_tuple(conn, iterpool, "cs",
+ propname, propval));
}
svn_pool_destroy(iterpool);
}
@@ -463,98 +591,332 @@ svn_error_t *svn_ra_svn_write_proplist(svn_ra_svn_conn_t *conn,
return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_start_list(svn_ra_svn_conn_t *conn, apr_pool_t *pool)
+svn_error_t *
+svn_ra_svn__start_list(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
{
+ if (conn->write_pos + 2 <= sizeof(conn->write_buf))
+ {
+ conn->write_buf[conn->write_pos] = '(';
+ conn->write_buf[conn->write_pos+1] = ' ';
+ conn->write_pos += 2;
+ return SVN_NO_ERROR;
+ }
+
return writebuf_write(conn, pool, "( ", 2);
}
-svn_error_t *svn_ra_svn_end_list(svn_ra_svn_conn_t *conn, apr_pool_t *pool)
+svn_error_t *
+svn_ra_svn__end_list(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
{
+ if (conn->write_pos + 2 <= sizeof(conn->write_buf))
+ {
+ conn->write_buf[conn->write_pos] = ')';
+ conn->write_buf[conn->write_pos+1] = ' ';
+ conn->write_pos += 2;
+ return SVN_NO_ERROR;
+ }
+
return writebuf_write(conn, pool, ") ", 2);
}
-svn_error_t *svn_ra_svn_flush(svn_ra_svn_conn_t *conn, apr_pool_t *pool)
+svn_error_t *
+svn_ra_svn__flush(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
{
- return writebuf_flush(conn, pool);
+ SVN_ERR(writebuf_flush(conn, pool));
+ conn->may_check_for_error = TRUE;
+
+ return SVN_NO_ERROR;
}
/* --- WRITING TUPLES --- */
+static svn_error_t *
+vwrite_tuple_cstring(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ const char *cstr = va_arg(*ap, const char *);
+ SVN_ERR_ASSERT(cstr);
+ return svn_ra_svn__write_cstring(conn, pool, cstr);
+}
+
+static svn_error_t *
+vwrite_tuple_cstring_opt(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ const char *cstr = va_arg(*ap, const char *);
+ return cstr ? svn_ra_svn__write_cstring(conn, pool, cstr) : SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_tuple_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ const svn_string_t *str = va_arg(*ap, const svn_string_t *);
+ SVN_ERR_ASSERT(str);
+ return svn_ra_svn__write_string(conn, pool, str);
+}
+
+static svn_error_t *
+vwrite_tuple_string_opt(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ const svn_string_t *str = va_arg(*ap, const svn_string_t *);
+ return str ? svn_ra_svn__write_string(conn, pool, str) : SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_tuple_word(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ const char *cstr = va_arg(*ap, const char *);
+ SVN_ERR_ASSERT(cstr);
+ return svn_ra_svn__write_word(conn, pool, cstr);
+}
+
+static svn_error_t *
+vwrite_tuple_word_opt(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ const char *cstr = va_arg(*ap, const char *);
+ return cstr ? svn_ra_svn__write_word(conn, pool, cstr) : SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_tuple_revision(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ svn_revnum_t rev = va_arg(*ap, svn_revnum_t);
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(rev));
+ return svn_ra_svn__write_number(conn, pool, rev);
+}
+
+static svn_error_t *
+vwrite_tuple_revision_opt(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ svn_revnum_t rev = va_arg(*ap, svn_revnum_t);
+ return SVN_IS_VALID_REVNUM(rev)
+ ? svn_ra_svn__write_number(conn, pool, rev)
+ : SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_tuple_number(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ return svn_ra_svn__write_number(conn, pool, va_arg(*ap, apr_uint64_t));
+}
+
+static svn_error_t *
+vwrite_tuple_boolean(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list *ap)
+{
+ const char *cstr = va_arg(*ap, svn_boolean_t) ? "true" : "false";
+ return svn_ra_svn__write_word(conn, pool, cstr);
+}
+
+static svn_error_t *
+write_tuple_cstring(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *cstr)
+{
+ SVN_ERR_ASSERT(cstr);
+ return svn_ra_svn__write_cstring(conn, pool, cstr);
+}
+
+static svn_error_t *
+write_tuple_cstring_opt(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *cstr)
+{
+ return cstr ? svn_ra_svn__write_cstring(conn, pool, cstr) : SVN_NO_ERROR;
+}
+
+static svn_error_t *
+write_tuple_string(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const svn_string_t *str)
+{
+ SVN_ERR_ASSERT(str);
+ return svn_ra_svn__write_string(conn, pool, str);
+}
+
+static svn_error_t *
+write_tuple_string_opt(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const svn_string_t *str)
+{
+ return str ? svn_ra_svn__write_string(conn, pool, str) : SVN_NO_ERROR;
+}
+
+static svn_error_t *
+write_tuple_start_list(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
+{
+ return svn_ra_svn__start_list(conn, pool);
+}
+
+static svn_error_t *
+write_tuple_end_list(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
+{
+ return svn_ra_svn__end_list(conn, pool);
+}
+
+static svn_error_t *
+write_tuple_revision(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev)
+{
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(rev));
+ return svn_ra_svn__write_number(conn, pool, rev);
+}
+
+static svn_error_t *
+write_tuple_revision_opt(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev)
+{
+ return SVN_IS_VALID_REVNUM(rev)
+ ? svn_ra_svn__write_number(conn, pool, rev)
+ : SVN_NO_ERROR;
+}
+
+static svn_error_t *
+write_tuple_boolean(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_boolean_t value)
+{
+ const char *cstr = value ? "true" : "false";
+ return svn_ra_svn__write_word(conn, pool, cstr);
+}
+
+static svn_error_t *
+write_tuple_depth(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_depth_t depth)
+{
+ return svn_ra_svn__write_word(conn, pool, svn_depth_to_word(depth));
+}
+
+
+static svn_error_t *
+write_cmd_add_node(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *parent_token,
+ const char *token,
+ const char *copy_path,
+ svn_revnum_t copy_rev)
+{
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_cstring(conn, pool, parent_token));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_cstring_opt(conn, pool, copy_path));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, copy_rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+write_cmd_open_node(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *parent_token,
+ const char *token,
+ svn_revnum_t rev)
+{
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_cstring(conn, pool, parent_token));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+write_cmd_change_node_prop(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *token,
+ const char *name,
+ const svn_string_t *value)
+{
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(write_tuple_cstring(conn, pool, name));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_string_opt(conn, pool, value));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+write_cmd_absent_node(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *token)
+{
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+
+ return SVN_NO_ERROR;
+}
+
+
+
+
static svn_error_t *vwrite_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- const char *fmt, va_list ap)
+ const char *fmt, va_list *ap)
{
svn_boolean_t opt = FALSE;
- svn_revnum_t rev;
- const char *cstr;
- const svn_string_t *str;
if (*fmt == '!')
fmt++;
else
- SVN_ERR(svn_ra_svn_start_list(conn, pool));
+ SVN_ERR(svn_ra_svn__start_list(conn, pool));
for (; *fmt; fmt++)
{
- if (*fmt == 'n' && !opt)
- SVN_ERR(svn_ra_svn_write_number(conn, pool, va_arg(ap, apr_uint64_t)));
- else if (*fmt == 'r')
- {
- rev = va_arg(ap, svn_revnum_t);
- SVN_ERR_ASSERT(opt || SVN_IS_VALID_REVNUM(rev));
- if (SVN_IS_VALID_REVNUM(rev))
- SVN_ERR(svn_ra_svn_write_number(conn, pool, rev));
- }
+ if (*fmt == 'c')
+ SVN_ERR(opt ? vwrite_tuple_cstring_opt(conn, pool, ap)
+ : vwrite_tuple_cstring(conn, pool, ap));
else if (*fmt == 's')
- {
- str = va_arg(ap, const svn_string_t *);
- SVN_ERR_ASSERT(opt || str);
- if (str)
- SVN_ERR(svn_ra_svn_write_string(conn, pool, str));
- }
- else if (*fmt == 'c')
- {
- cstr = va_arg(ap, const char *);
- SVN_ERR_ASSERT(opt || cstr);
- if (cstr)
- SVN_ERR(svn_ra_svn_write_cstring(conn, pool, cstr));
- }
- else if (*fmt == 'w')
- {
- cstr = va_arg(ap, const char *);
- SVN_ERR_ASSERT(opt || cstr);
- if (cstr)
- SVN_ERR(svn_ra_svn_write_word(conn, pool, cstr));
- }
- else if (*fmt == 'b' && !opt)
- {
- cstr = va_arg(ap, svn_boolean_t) ? "true" : "false";
- SVN_ERR(svn_ra_svn_write_word(conn, pool, cstr));
- }
- else if (*fmt == '?')
- opt = TRUE;
+ SVN_ERR(opt ? vwrite_tuple_string_opt(conn, pool, ap)
+ : vwrite_tuple_string(conn, pool, ap));
else if (*fmt == '(' && !opt)
- SVN_ERR(svn_ra_svn_start_list(conn, pool));
+ SVN_ERR(write_tuple_start_list(conn, pool));
else if (*fmt == ')')
{
- SVN_ERR(svn_ra_svn_end_list(conn, pool));
+ SVN_ERR(write_tuple_end_list(conn, pool));
opt = FALSE;
}
+ else if (*fmt == '?')
+ opt = TRUE;
+ else if (*fmt == 'w')
+ SVN_ERR(opt ? vwrite_tuple_word_opt(conn, pool, ap)
+ : vwrite_tuple_word(conn, pool, ap));
+ else if (*fmt == 'r')
+ SVN_ERR(opt ? vwrite_tuple_revision_opt(conn, pool, ap)
+ : vwrite_tuple_revision(conn, pool, ap));
+ else if (*fmt == 'n' && !opt)
+ SVN_ERR(vwrite_tuple_number(conn, pool, ap));
+ else if (*fmt == 'b' && !opt)
+ SVN_ERR(vwrite_tuple_boolean(conn, pool, ap));
else if (*fmt == '!' && !*(fmt + 1))
return SVN_NO_ERROR;
else
SVN_ERR_MALFUNCTION();
}
- SVN_ERR(svn_ra_svn_end_list(conn, pool));
+ SVN_ERR(svn_ra_svn__end_list(conn, pool));
return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_write_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__write_tuple(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *fmt, ...)
{
svn_error_t *err;
va_list ap;
va_start(ap, fmt);
- err = vwrite_tuple(conn, pool, fmt, ap);
+ err = vwrite_tuple(conn, pool, fmt, &ap);
va_end(ap);
return err;
}
@@ -613,7 +975,7 @@ static svn_error_t *read_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
? len
: SUSPICIOUSLY_HUGE_STRING_SIZE_THRESHOLD;
- svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len + 1);
+ svn_stringbuf_ensure(stringbuf, stringbuf->len + readbuf_len);
dest = stringbuf->data + stringbuf->len;
}
@@ -659,7 +1021,8 @@ static svn_error_t *read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
if (!svn_ctype_isdigit(c))
break;
val = val * 10 + (c - '0');
- if ((val / 10) != prev_val) /* val wrapped past maximum value */
+ /* val wrapped past maximum value? */
+ if (prev_val >= (APR_UINT64_MAX / 10) && (val / 10) != prev_val)
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("Number is larger than maximum"));
}
@@ -713,8 +1076,99 @@ static svn_error_t *read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- svn_ra_svn_item_t **item)
+/* Given the first non-whitespace character FIRST_CHAR, read the first
+ * command (word) encountered in CONN into *ITEM. If ITEM is NULL, skip
+ * to the end of the current list. Use POOL for allocations. */
+static svn_error_t *
+read_command_only(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
+ const char **item, char first_char)
+{
+ char c = first_char;
+
+ /* Determine the item type and read it in. Make sure that c is the
+ * first character at the end of the item so we can test to make
+ * sure it's whitespace. */
+ if (svn_ctype_isdigit(c))
+ {
+ /* It's a number or a string. Read the number part, either way. */
+ apr_uint64_t val, prev_val=0;
+ val = c - '0';
+ while (1)
+ {
+ prev_val = val;
+ SVN_ERR(readbuf_getchar(conn, pool, &c));
+ if (!svn_ctype_isdigit(c))
+ break;
+ val = val * 10 + (c - '0');
+ if (prev_val >= (APR_UINT64_MAX / 10)) /* > maximum value? */
+ return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+ _("Number is larger than maximum"));
+ }
+ if (c == ':')
+ {
+ /* It's a string. */
+ SVN_ERR(readbuf_skip(conn, val));
+ SVN_ERR(readbuf_getchar(conn, pool, &c));
+ }
+ }
+ else if (svn_ctype_isalpha(c))
+ {
+ /* It's a word. */
+ if (item)
+ {
+ /* This is the word we want to read */
+
+ char *buf = apr_palloc(pool, 32);
+ apr_size_t len = 1;
+ buf[0] = c;
+
+ while (1)
+ {
+ SVN_ERR(readbuf_getchar(conn, pool, &c));
+ if (!svn_ctype_isalnum(c) && c != '-')
+ break;
+ buf[len] = c;
+ if (++len == 32)
+ return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
+ _("Word too long"));
+ }
+ buf[len] = 0;
+ *item = buf;
+ }
+ else
+ {
+ /* we don't need the actual word, just skip it */
+ do
+ {
+ SVN_ERR(readbuf_getchar(conn, pool, &c));
+ }
+ while (svn_ctype_isalnum(c) || c == '-');
+ }
+ }
+ else if (c == '(')
+ {
+ /* Read in the list items. */
+ while (1)
+ {
+ SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));
+ if (c == ')')
+ break;
+
+ if (item && *item == NULL)
+ SVN_ERR(read_command_only(conn, pool, item, c));
+ else
+ SVN_ERR(read_command_only(conn, pool, NULL, c));
+ }
+ SVN_ERR(readbuf_getchar(conn, pool, &c));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__read_item(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_ra_svn_item_t **item)
{
char c;
@@ -725,8 +1179,9 @@ svn_error_t *svn_ra_svn_read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
return read_item(conn, pool, *item, c, 0);
}
-svn_error_t *svn_ra_svn_skip_leading_garbage(svn_ra_svn_conn_t *conn,
- apr_pool_t *pool)
+svn_error_t *
+svn_ra_svn__skip_leading_garbage(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
{
return readbuf_skip_leading_garbage(conn, pool);
}
@@ -831,9 +1286,10 @@ static svn_error_t *vparse_tuple(const apr_array_header_t *items, apr_pool_t *po
return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_parse_tuple(const apr_array_header_t *list,
- apr_pool_t *pool,
- const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__parse_tuple(const apr_array_header_t *list,
+ apr_pool_t *pool,
+ const char *fmt, ...)
{
svn_error_t *err;
va_list ap;
@@ -844,14 +1300,16 @@ svn_error_t *svn_ra_svn_parse_tuple(const apr_array_header_t *list,
return err;
}
-svn_error_t *svn_ra_svn_read_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__read_tuple(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *fmt, ...)
{
va_list ap;
svn_ra_svn_item_t *item;
svn_error_t *err;
- SVN_ERR(svn_ra_svn_read_item(conn, pool, &item));
+ SVN_ERR(svn_ra_svn__read_item(conn, pool, &item));
if (item->kind != SVN_RA_SVN_LIST)
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("Malformed network data"));
@@ -861,9 +1319,23 @@ svn_error_t *svn_ra_svn_read_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
return err;
}
-svn_error_t *svn_ra_svn_parse_proplist(const apr_array_header_t *list,
- apr_pool_t *pool,
- apr_hash_t **props)
+svn_error_t *
+svn_ra_svn__read_command_only(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char **command)
+{
+ char c;
+ SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));
+
+ *command = NULL;
+ return read_command_only(conn, pool, command, c);
+}
+
+
+svn_error_t *
+svn_ra_svn__parse_proplist(const apr_array_header_t *list,
+ apr_pool_t *pool,
+ apr_hash_t **props)
{
char *name;
svn_string_t *value;
@@ -877,8 +1349,9 @@ svn_error_t *svn_ra_svn_parse_proplist(const apr_array_header_t *list,
if (elt->kind != SVN_RA_SVN_LIST)
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("Proplist element not a list"));
- SVN_ERR(svn_ra_svn_parse_tuple(elt->u.list, pool, "cs", &name, &value));
- apr_hash_set(*props, name, APR_HASH_KEY_STRING, value);
+ SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, pool, "cs",
+ &name, &value));
+ svn_hash_sets(*props, name, value);
}
return SVN_NO_ERROR;
@@ -924,8 +1397,8 @@ svn_error_t *svn_ra_svn__handle_failure_status(const apr_array_header_t *params,
if (elt->kind != SVN_RA_SVN_LIST)
return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
_("Malformed error list"));
- SVN_ERR(svn_ra_svn_parse_tuple(elt->u.list, subpool, "nccn", &apr_err,
- &message, &file, &line));
+ SVN_ERR(svn_ra_svn__parse_tuple(elt->u.list, subpool, "nccn",
+ &apr_err, &message, &file, &line));
/* The message field should have been optional, but we can't
easily change that, so "" means a nonexistent message. */
if (!*message)
@@ -954,16 +1427,17 @@ svn_error_t *svn_ra_svn__handle_failure_status(const apr_array_header_t *params,
return err;
}
-svn_error_t *svn_ra_svn_read_cmd_response(svn_ra_svn_conn_t *conn,
- apr_pool_t *pool,
- const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__read_cmd_response(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *fmt, ...)
{
va_list ap;
const char *status;
apr_array_header_t *params;
svn_error_t *err;
- SVN_ERR(svn_ra_svn_read_tuple(conn, pool, "wl", &status, &params));
+ SVN_ERR(svn_ra_svn__read_tuple(conn, pool, "wl", &status, &params));
if (strcmp(status, "success") == 0)
{
va_start(ap, fmt);
@@ -981,11 +1455,12 @@ svn_error_t *svn_ra_svn_read_cmd_response(svn_ra_svn_conn_t *conn,
status);
}
-svn_error_t *svn_ra_svn_handle_commands2(svn_ra_svn_conn_t *conn,
- apr_pool_t *pool,
- const svn_ra_svn_cmd_entry_t *commands,
- void *baton,
- svn_boolean_t error_on_disconnect)
+svn_error_t *
+svn_ra_svn__handle_commands2(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const svn_ra_svn_cmd_entry_t *commands,
+ void *baton,
+ svn_boolean_t error_on_disconnect)
{
apr_pool_t *subpool = svn_pool_create(pool);
apr_pool_t *iterpool = svn_pool_create(subpool);
@@ -996,12 +1471,12 @@ svn_error_t *svn_ra_svn_handle_commands2(svn_ra_svn_conn_t *conn,
apr_hash_t *cmd_hash = apr_hash_make(subpool);
for (command = commands; command->cmdname; command++)
- apr_hash_set(cmd_hash, command->cmdname, APR_HASH_KEY_STRING, command);
+ svn_hash_sets(cmd_hash, command->cmdname, command);
while (1)
{
svn_pool_clear(iterpool);
- err = svn_ra_svn_read_tuple(conn, iterpool, "wl", &cmdname, &params);
+ err = svn_ra_svn__read_tuple(conn, iterpool, "wl", &cmdname, &params);
if (err)
{
if (!error_on_disconnect
@@ -1013,20 +1488,20 @@ svn_error_t *svn_ra_svn_handle_commands2(svn_ra_svn_conn_t *conn,
}
return err;
}
- command = apr_hash_get(cmd_hash, cmdname, APR_HASH_KEY_STRING);
+ command = svn_hash_gets(cmd_hash, cmdname);
if (command)
err = (*command->handler)(conn, iterpool, params, baton);
else
{
err = svn_error_createf(SVN_ERR_RA_SVN_UNKNOWN_CMD, NULL,
- _("Unknown command '%s'"), cmdname);
+ _("Unknown editor command '%s'"), cmdname);
err = svn_error_create(SVN_ERR_RA_SVN_CMD_ERR, err, NULL);
}
if (err && err->apr_err == SVN_ERR_RA_SVN_CMD_ERR)
{
- write_err = svn_ra_svn_write_cmd_failure(
+ write_err = svn_ra_svn__write_cmd_failure(
conn, iterpool,
svn_ra_svn__locate_real_error_child(err));
svn_error_clear(err);
@@ -1044,69 +1519,771 @@ svn_error_t *svn_ra_svn_handle_commands2(svn_ra_svn_conn_t *conn,
return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_handle_commands(svn_ra_svn_conn_t *conn,
- apr_pool_t *pool,
- const svn_ra_svn_cmd_entry_t *commands,
- void *baton)
+svn_error_t *
+svn_ra_svn__write_cmd_target_rev(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev)
{
- return svn_ra_svn_handle_commands2(conn, pool, commands, baton, TRUE);
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( target-rev ( ", 15));
+ SVN_ERR(write_tuple_revision(conn, pool, rev));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_write_cmd(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
- const char *cmdname, const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__write_cmd_open_root(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev,
+ const char *token)
{
- va_list ap;
- svn_error_t *err;
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( open-root ( ", 14));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_delete_entry(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ svn_revnum_t rev,
+ const char *token)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( delete-entry ( ", 17));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_add_dir(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *parent_token,
+ const char *token,
+ const char *copy_path,
+ svn_revnum_t copy_rev)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( add-dir ( ", 12));
+ SVN_ERR(write_cmd_add_node(conn, pool, path, parent_token, token,
+ copy_path, copy_rev));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_open_dir(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *parent_token,
+ const char *token,
+ svn_revnum_t rev)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( open-dir ( ", 13));
+ SVN_ERR(write_cmd_open_node(conn, pool, path, parent_token, token, rev));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_change_dir_prop(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *token,
+ const char *name,
+ const svn_string_t *value)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( change-dir-prop ( ", 20));
+ SVN_ERR(write_cmd_change_node_prop(conn, pool, token, name, value));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_close_dir(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *token)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( close-dir ( ", 14));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_absent_dir(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *parent_token)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( absent-dir ( ", 15));
+ SVN_ERR(write_cmd_absent_node(conn, pool, path, parent_token));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_add_file(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *parent_token,
+ const char *token,
+ const char *copy_path,
+ svn_revnum_t copy_rev)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( add-file ( ", 13));
+ SVN_ERR(write_cmd_add_node(conn, pool, path, parent_token, token,
+ copy_path, copy_rev));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_open_file(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *parent_token,
+ const char *token,
+ svn_revnum_t rev)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( open-file ( ", 14));
+ SVN_ERR(write_cmd_open_node(conn, pool, path, parent_token, token, rev));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_change_file_prop(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *token,
+ const char *name,
+ const svn_string_t *value)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( change-file-prop ( ", 21));
+ SVN_ERR(write_cmd_change_node_prop(conn, pool, token, name, value));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_close_file(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *token,
+ const char *text_checksum)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( close-file ( ", 15));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_cstring_opt(conn, pool, text_checksum));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_absent_file(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *parent_token)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( absent-file ( ", 16));
+ SVN_ERR(write_cmd_absent_node(conn, pool, path, parent_token));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_textdelta_chunk(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *token,
+ const svn_string_t *chunk)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( textdelta-chunk ( ", 20));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(write_tuple_string(conn, pool, chunk));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_textdelta_end(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *token)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( textdelta-end ( ", 18));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_apply_textdelta(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *token,
+ const char *base_checksum)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( apply-textdelta ( ", 20));
+ SVN_ERR(write_tuple_cstring(conn, pool, token));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_cstring_opt(conn, pool, base_checksum));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_close_edit(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
+{
+ return writebuf_write_short_string(conn, pool, "( close-edit ( ) ) ", 19);
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_abort_edit(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
+{
+ return writebuf_write_short_string(conn, pool, "( abort-edit ( ) ) ", 19);
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_set_path(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ svn_revnum_t rev,
+ svn_boolean_t start_empty,
+ const char *lock_token,
+ svn_depth_t depth)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( set-path ( ", 13));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_revision(conn, pool, rev));
+ SVN_ERR(write_tuple_boolean(conn, pool, start_empty));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_cstring_opt(conn, pool, lock_token));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_depth(conn, pool, depth));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_delete_path(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( delete-path ( ", 16));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_link_path(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *url,
+ svn_revnum_t rev,
+ svn_boolean_t start_empty,
+ const char *lock_token,
+ svn_depth_t depth)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( link-path ( ", 14));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_cstring(conn, pool, url));
+ SVN_ERR(write_tuple_revision(conn, pool, rev));
+ SVN_ERR(write_tuple_boolean(conn, pool, start_empty));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_cstring_opt(conn, pool,lock_token));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_depth(conn, pool, depth));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_finish_report(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
+{
+ return writebuf_write_short_string(conn, pool, "( finish-report ( ) ) ", 22);
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_abort_report(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
+{
+ return writebuf_write_short_string(conn, pool, "( abort-report ( ) ) ", 21);
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_reparent(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *url)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( reparent ( ", 13));
+ SVN_ERR(write_tuple_cstring(conn, pool, url));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_get_latest_rev(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
+{
+ return writebuf_write_short_string(conn, pool, "( get-latest-rev ( ) ) ", 23);
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_get_dated_rev(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ apr_time_t tm)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( get-dated-rev ( ", 18));
+ SVN_ERR(write_tuple_cstring(conn, pool, svn_time_to_cstring(tm, pool)));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_change_rev_prop2(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev,
+ const char *name,
+ const svn_string_t *value,
+ svn_boolean_t dont_care,
+ const svn_string_t *old_value)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( change-rev-prop2 ( ", 21));
+ SVN_ERR(write_tuple_revision(conn, pool, rev));
+ SVN_ERR(write_tuple_cstring(conn, pool, name));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_string_opt(conn, pool, value));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_boolean(conn, pool, dont_care));
+ SVN_ERR(write_tuple_string_opt(conn, pool, old_value));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_change_rev_prop(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev,
+ const char *name,
+ const svn_string_t *value)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( change-rev-prop ( ", 20));
+ SVN_ERR(write_tuple_revision(conn, pool, rev));
+ SVN_ERR(write_tuple_cstring(conn, pool, name));
+ SVN_ERR(write_tuple_string_opt(conn, pool, value));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_rev_proplist(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( rev-proplist ( ", 17));
+ SVN_ERR(write_tuple_revision(conn, pool, rev));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_rev_prop(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev,
+ const char *name)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( rev-prop ( ", 13));
+ SVN_ERR(write_tuple_revision(conn, pool, rev));
+ SVN_ERR(write_tuple_cstring(conn, pool, name));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_get_file(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ svn_revnum_t rev,
+ svn_boolean_t props,
+ svn_boolean_t stream)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( get-file ( ", 13));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_boolean(conn, pool, props));
+ SVN_ERR(write_tuple_boolean(conn, pool, stream));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_update(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev,
+ const char *target,
+ svn_boolean_t recurse,
+ svn_depth_t depth,
+ svn_boolean_t send_copyfrom_args,
+ svn_boolean_t ignore_ancestry)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( update ( ", 11));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_cstring(conn, pool, target));
+ SVN_ERR(write_tuple_boolean(conn, pool, recurse));
+ SVN_ERR(write_tuple_depth(conn, pool, depth));
+ SVN_ERR(write_tuple_boolean(conn, pool, send_copyfrom_args));
+ SVN_ERR(write_tuple_boolean(conn, pool, ignore_ancestry));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_switch(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev,
+ const char *target,
+ svn_boolean_t recurse,
+ const char *switch_url,
+ svn_depth_t depth,
+ svn_boolean_t send_copyfrom_args,
+ svn_boolean_t ignore_ancestry)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( switch ( ", 11));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_cstring(conn, pool, target));
+ SVN_ERR(write_tuple_boolean(conn, pool, recurse));
+ SVN_ERR(write_tuple_cstring(conn, pool, switch_url));
+ SVN_ERR(write_tuple_depth(conn, pool, depth));
+ SVN_ERR(write_tuple_boolean(conn, pool, send_copyfrom_args));
+ SVN_ERR(write_tuple_boolean(conn, pool, ignore_ancestry));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_status(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *target,
+ svn_boolean_t recurse,
+ svn_revnum_t rev,
+ svn_depth_t depth)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( status ( ", 11));
+ SVN_ERR(write_tuple_cstring(conn, pool, target));
+ SVN_ERR(write_tuple_boolean(conn, pool, recurse));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_depth(conn, pool, depth));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_diff(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev,
+ const char *target,
+ svn_boolean_t recurse,
+ svn_boolean_t ignore_ancestry,
+ const char *versus_url,
+ svn_boolean_t text_deltas,
+ svn_depth_t depth)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( diff ( ", 9));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_cstring(conn, pool, target));
+ SVN_ERR(write_tuple_boolean(conn, pool, recurse));
+ SVN_ERR(write_tuple_boolean(conn, pool, ignore_ancestry));
+ SVN_ERR(write_tuple_cstring(conn, pool, versus_url));
+ SVN_ERR(write_tuple_boolean(conn, pool, text_deltas));
+ SVN_ERR(write_tuple_depth(conn, pool, depth));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_check_path(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ svn_revnum_t rev)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( check-path ( ", 15));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
- SVN_ERR(svn_ra_svn_start_list(conn, pool));
- SVN_ERR(svn_ra_svn_write_word(conn, pool, cmdname));
- va_start(ap, fmt);
- err = vwrite_tuple(conn, pool, fmt, ap);
- va_end(ap);
- if (err)
- return err;
- SVN_ERR(svn_ra_svn_end_list(conn, pool));
return SVN_NO_ERROR;
}
-svn_error_t *svn_ra_svn_write_cmd_response(svn_ra_svn_conn_t *conn,
- apr_pool_t *pool,
- const char *fmt, ...)
+svn_error_t *
+svn_ra_svn__write_cmd_stat(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ svn_revnum_t rev)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( stat ( ", 9));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, rev));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_get_file_revs(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ svn_revnum_t start,
+ svn_revnum_t end,
+ svn_boolean_t include_merged_revisions)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( get-file-revs ( ", 18));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, start));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, end));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_boolean(conn, pool, include_merged_revisions));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_lock(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *comment,
+ svn_boolean_t steal_lock,
+ svn_revnum_t revnum)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( lock ( ", 9));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_cstring_opt(conn, pool, comment));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_boolean(conn, pool, steal_lock));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, revnum));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_unlock(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ const char *token,
+ svn_boolean_t break_lock)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( unlock ( ", 11));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_cstring_opt(conn, pool, token));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(write_tuple_boolean(conn, pool, break_lock));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_get_lock(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( get-lock ( ", 13));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_get_locks(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ svn_depth_t depth)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( get-locks ( ", 14));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_depth(conn, pool, depth));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_replay(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t rev,
+ svn_revnum_t low_water_mark,
+ svn_boolean_t send_deltas)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( replay ( ", 11));
+ SVN_ERR(write_tuple_revision(conn, pool, rev));
+ SVN_ERR(write_tuple_revision(conn, pool, low_water_mark));
+ SVN_ERR(write_tuple_boolean(conn, pool, send_deltas));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_replay_range(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ svn_revnum_t start_revision,
+ svn_revnum_t end_revision,
+ svn_revnum_t low_water_mark,
+ svn_boolean_t send_deltas)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( replay-range ( ", 17));
+ SVN_ERR(write_tuple_revision(conn, pool, start_revision));
+ SVN_ERR(write_tuple_revision(conn, pool, end_revision));
+ SVN_ERR(write_tuple_revision(conn, pool, low_water_mark));
+ SVN_ERR(write_tuple_boolean(conn, pool, send_deltas));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_get_deleted_rev(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ svn_revnum_t peg_revision,
+ svn_revnum_t end_revision)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( get-deleted-rev ( ", 20));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_revision(conn, pool, peg_revision));
+ SVN_ERR(write_tuple_revision(conn, pool, end_revision));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_get_iprops(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *path,
+ svn_revnum_t revision)
+{
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( get-iprops ( ", 15));
+ SVN_ERR(write_tuple_cstring(conn, pool, path));
+ SVN_ERR(write_tuple_start_list(conn, pool));
+ SVN_ERR(write_tuple_revision_opt(conn, pool, revision));
+ SVN_ERR(write_tuple_end_list(conn, pool));
+ SVN_ERR(writebuf_write_short_string(conn, pool, ") ) ", 4));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_ra_svn__write_cmd_finish_replay(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool)
+{
+ return writebuf_write_short_string(conn, pool, "( finish-replay ( ) ) ", 22);
+}
+
+svn_error_t *svn_ra_svn__write_cmd_response(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool,
+ const char *fmt, ...)
{
va_list ap;
svn_error_t *err;
- SVN_ERR(svn_ra_svn_start_list(conn, pool));
- SVN_ERR(svn_ra_svn_write_word(conn, pool, "success"));
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( success ", 10));
va_start(ap, fmt);
- err = vwrite_tuple(conn, pool, fmt, ap);
+ err = vwrite_tuple(conn, pool, fmt, &ap);
va_end(ap);
- if (err)
- return err;
- SVN_ERR(svn_ra_svn_end_list(conn, pool));
- return SVN_NO_ERROR;
+ return err ? svn_error_trace(err) : svn_ra_svn__end_list(conn, pool);
}
-svn_error_t *svn_ra_svn_write_cmd_failure(svn_ra_svn_conn_t *conn,
- apr_pool_t *pool, svn_error_t *err)
+svn_error_t *svn_ra_svn__write_cmd_failure(svn_ra_svn_conn_t *conn,
+ apr_pool_t *pool, svn_error_t *err)
{
char buffer[128];
- SVN_ERR(svn_ra_svn_start_list(conn, pool));
- SVN_ERR(svn_ra_svn_write_word(conn, pool, "failure"));
- SVN_ERR(svn_ra_svn_start_list(conn, pool));
+ SVN_ERR(writebuf_write_short_string(conn, pool, "( failure ( ", 12));
for (; err; err = err->child)
{
- const char *msg = svn_err_best_message(err, buffer, sizeof(buffer));
+ const char *msg;
+
+#ifdef SVN_ERR__TRACING
+ if (svn_error__is_tracing_link(err))
+ msg = err->message;
+ else
+#endif
+ msg = svn_err_best_message(err, buffer, sizeof(buffer));
/* The message string should have been optional, but we can't
easily change that, so marshal nonexistent messages as "". */
- SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "nccn",
- (apr_uint64_t) err->apr_err,
- msg ? msg : "",
- err->file ? err->file : "",
- (apr_uint64_t) err->line));
+ SVN_ERR(svn_ra_svn__write_tuple(conn, pool, "nccn",
+ (apr_uint64_t) err->apr_err,
+ msg ? msg : "",
+ err->file ? err->file : "",
+ (apr_uint64_t) err->line));
}
- SVN_ERR(svn_ra_svn_end_list(conn, pool));
- SVN_ERR(svn_ra_svn_end_list(conn, pool));
- return SVN_NO_ERROR;
+ return writebuf_write_short_string(conn, pool, ") ) ", 4);
}