subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1388276 - in /subversion/branches/10Gb/subversion: include/svn_ra_svn.h libsvn_ra_svn/editorp.c libsvn_ra_svn/marshal.c
Date Fri, 21 Sep 2012 00:04:57 GMT
Author: stefan2
Date: Fri Sep 21 00:04:56 2012
New Revision: 1388276

URL: http://svn.apache.org/viewvc?rev=1388276&view=rev
Log:
On the 10Gb branch: Instead of parsing a command's parameter format
dynamically, make the list of used commands part of the interface.
Implement hard-coded parameter sets for these commands.

* subversion/include/svn_ra_svn.h
  (svn_ra_svn_cmd_t): declare enum of all svn:// commands used by the server
  (svn_ra_svn_write_cmd): deprecate
  (svn_ra_svn_write_templated_cmd): new API function

* subversion/libsvn_ra_svn/editorp.c
  (check_for_error,
   ra_svn_target_rev,
   ra_svn_open_root, 
   ra_svn_delete_entry,
   ra_svn_add_dir,
   ra_svn_open_dir,
   ra_svn_close_dir,
   ra_svn_absent_dir,
   ra_svn_add_file,
   ra_svn_open_file,
   ra_svn_close_file,
   ra_svn_absent_file,
   ra_svn_close_edit, 
   ra_svn_abort_edit): switch to using templated commands

* subversion/libsvn_ra_svn/marshal.c
  (vwrite_tuple_cstring,
   vwrite_tuple_cstring_opt,
   vwrite_tuple_string,
   vwrite_tuple_string_opt,
   vwrite_tuple_start_list,
   vwrite_tuple_end_list,
   vwrite_tuple_word,
   vwrite_tuple_word_opt,
   vwrite_tuple_revision,
   vwrite_tuple_revision_opt,
   vwrite_tuple_number,
   vwrite_tuple_boolean): new utilities to write a parameter
  (vwrite_cmd_open_root,
   vwrite_cmd_delete_entry,
   vwrite_cmd_add_dir,
   vwrite_cmd_open_dir,
   vwrite_cmd_change_dir_prop,
   vwrite_cmd_absent_dir,
   vwrite_cmd_add_file,
   vwrite_cmd_open_file,
   vwrite_cmd_change_file_prop,
   vwrite_cmd_close_file,
   vwrite_cmd_absent_file,
   vwrite_cmd_textdelta_chunk,
   vwrite_cmd_apply_textdelta,
   vwrite_cmd_no_op): hard-coded parameter sequences for commands
  (vwrite_tuple_func, 
   cmd_template_t,
   cmd_templates): command lookup table
  (vwrite_tuple): shorten using the new parameter utilities
  (svn_ra_svn_write_templated_cmd): implement

Modified:
    subversion/branches/10Gb/subversion/include/svn_ra_svn.h
    subversion/branches/10Gb/subversion/libsvn_ra_svn/editorp.c
    subversion/branches/10Gb/subversion/libsvn_ra_svn/marshal.c

Modified: subversion/branches/10Gb/subversion/include/svn_ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/subversion/include/svn_ra_svn.h?rev=1388276&r1=1388275&r2=1388276&view=diff
==============================================================================
--- subversion/branches/10Gb/subversion/include/svn_ra_svn.h (original)
+++ subversion/branches/10Gb/subversion/include/svn_ra_svn.h Fri Sep 21 00:04:56 2012
@@ -158,6 +158,34 @@ typedef struct svn_ra_svn_item_t
 typedef svn_error_t *(*svn_ra_svn_edit_callback)(void *baton);
 
 /**
+ * List of all commands supported by the SVN:// protocol.
+ *
+ * @since New in 1.9.
+ */
+typedef enum svn_ra_svn_cmd_t
+{
+  svn_ra_svn_cmd_target_rev,
+  svn_ra_svn_cmd_open_root,
+  svn_ra_svn_cmd_delete_entry,
+  svn_ra_svn_cmd_add_dir,
+  svn_ra_svn_cmd_open_dir,
+  svn_ra_svn_cmd_change_dir_prop,
+  svn_ra_svn_cmd_close_dir,
+  svn_ra_svn_cmd_absent_dir,
+  svn_ra_svn_cmd_add_file,
+  svn_ra_svn_cmd_open_file,
+  svn_ra_svn_cmd_change_file_prop,
+  svn_ra_svn_cmd_close_file,
+  svn_ra_svn_cmd_absent_file,
+  svn_ra_svn_cmd_textdelta_chunk,
+  svn_ra_svn_cmd_textdelta_end,
+  svn_ra_svn_cmd_apply_textdelta,
+  svn_ra_svn_cmd_close_edit,
+  svn_ra_svn_cmd_abort_edit,
+  svn_ra_svn_cmd__last
+} svn_ra_svn_cmd_t;
+
+/**
  * Set the shim callbacks to be used by @a conn to @a shim_callbacks.
  *
  * @note This is a private API, external consumers should not use it.
@@ -469,13 +497,26 @@ svn_ra_svn_handle_commands(svn_ra_svn_co
 
 /** Write a command over the network, using the same format string notation
  * as svn_ra_svn_write_tuple().
+ *
+ * @deprecated Provided for backward compatibility with the 1.9 API.
+ * Use svn_ra_svn_write_templated_cmd instead.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_ra_svn_write_cmd(svn_ra_svn_conn_t *conn,
                      apr_pool_t *pool,
                      const char *cmdname,
                      const char *fmt, ...);
 
+/** Write a command of type @a cmd over the network connection @a conn.
+ * The parameters to be provided are command-specific.  @a pool will be
+ * used for allocations.
+ */
+svn_error_t *
+svn_ra_svn_write_templated_cmd(svn_ra_svn_conn_t *conn,
+                               apr_pool_t *pool,
+                               svn_ra_svn_cmd_t cmd, ...);
+
 /** Write a successful command response over the network, using the
  * same format string notation as svn_ra_svn_write_tuple().  Do not use
  * partial tuples with this function; if you need to use partial

Modified: subversion/branches/10Gb/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/subversion/libsvn_ra_svn/editorp.c?rev=1388276&r1=1388275&r2=1388276&view=diff
==============================================================================
--- subversion/branches/10Gb/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/10Gb/subversion/libsvn_ra_svn/editorp.c Fri Sep 21 00:04:56 2012
@@ -127,7 +127,7 @@ static svn_error_t *check_for_error(ra_s
   if (svn_ra_svn__input_waiting(eb->conn, pool))
     {
       eb->got_status = TRUE;
-      SVN_ERR(svn_ra_svn_write_cmd(eb->conn, pool, "abort-edit", ""));
+      SVN_ERR(svn_ra_svn_write_templated_cmd(eb->conn, pool, svn_ra_svn_cmd_abort_edit));
       SVN_ERR(svn_ra_svn_read_cmd_response(eb->conn, pool, ""));
       /* We shouldn't get here if the consumer is doing its job. */
       return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
@@ -142,7 +142,7 @@ static svn_error_t *ra_svn_target_rev(vo
   ra_svn_edit_baton_t *eb = edit_baton;
 
   SVN_ERR(check_for_error(eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(eb->conn, pool, "target-rev", "r", rev));
+  SVN_ERR(svn_ra_svn_write_templated_cmd(eb->conn, pool, svn_ra_svn_cmd_target_rev, rev));
   return SVN_NO_ERROR;
 }
 
@@ -153,7 +153,7 @@ static svn_error_t *ra_svn_open_root(voi
   const char *token = make_token('d', eb, pool);
 
   SVN_ERR(check_for_error(eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(eb->conn, pool, "open-root", "(?r)c", rev,
+  SVN_ERR(svn_ra_svn_write_templated_cmd(eb->conn, pool, svn_ra_svn_cmd_open_root, rev,
                                token));
   *root_baton = ra_svn_make_baton(eb->conn, pool, eb, token);
   return SVN_NO_ERROR;
@@ -165,7 +165,7 @@ static svn_error_t *ra_svn_delete_entry(
   ra_svn_baton_t *b = parent_baton;
 
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "delete-entry", "c(?r)c",
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_delete_entry,
                                path, rev, b->token));
   return SVN_NO_ERROR;
 }
@@ -181,7 +181,7 @@ static svn_error_t *ra_svn_add_dir(const
   SVN_ERR_ASSERT((copy_path && SVN_IS_VALID_REVNUM(copy_rev))
                  || (!copy_path && !SVN_IS_VALID_REVNUM(copy_rev)));
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "add-dir", "ccc(?cr)", path,
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_add_dir, path,
                                b->token, token, copy_path, copy_rev));
   *child_baton = ra_svn_make_baton(b->conn, pool, b->eb, token);
   return SVN_NO_ERROR;
@@ -195,7 +195,7 @@ static svn_error_t *ra_svn_open_dir(cons
   const char *token = make_token('d', b->eb, pool);
 
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "open-dir", "ccc(?r)",
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_open_dir,
                                path, b->token, token, rev));
   *child_baton = ra_svn_make_baton(b->conn, pool, b->eb, token);
   return SVN_NO_ERROR;
@@ -208,7 +208,7 @@ static svn_error_t *ra_svn_change_dir_pr
   ra_svn_baton_t *b = dir_baton;
 
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "change-dir-prop", "cc(?s)",
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_change_dir_prop,
                                b->token, name, value));
   return SVN_NO_ERROR;
 }
@@ -218,7 +218,7 @@ static svn_error_t *ra_svn_close_dir(voi
   ra_svn_baton_t *b = dir_baton;
 
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "close-dir", "c", b->token));
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_close_dir, b->token));
   return SVN_NO_ERROR;
 }
 
@@ -233,7 +233,7 @@ static svn_error_t *ra_svn_absent_dir(co
     return SVN_NO_ERROR;
 
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "absent-dir", "cc", path,
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_absent_dir, path,
                                b->token));
   return SVN_NO_ERROR;
 }
@@ -251,7 +251,7 @@ static svn_error_t *ra_svn_add_file(cons
   SVN_ERR_ASSERT((copy_path && SVN_IS_VALID_REVNUM(copy_rev))
                  || (!copy_path && !SVN_IS_VALID_REVNUM(copy_rev)));
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "add-file", "ccc(?cr)", path,
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_add_file, path,
                                b->token, token, copy_path, copy_rev));
   *file_baton = ra_svn_make_baton(b->conn, pool, b->eb, token);
   return SVN_NO_ERROR;
@@ -267,7 +267,7 @@ static svn_error_t *ra_svn_open_file(con
   const char *token = make_token('c', b->eb, pool);
 
   SVN_ERR(check_for_error(b->eb, b->pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "open-file", "ccc(?r)",
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_open_file,
                                path, b->token, token, rev));
   *file_baton = ra_svn_make_baton(b->conn, pool, b->eb, token);
   return SVN_NO_ERROR;
@@ -282,7 +282,7 @@ static svn_error_t *ra_svn_svndiff_handl
   SVN_ERR(check_for_error(b->eb, b->pool));
   str.data = data;
   str.len = *len;
-  return svn_ra_svn_write_cmd(b->conn, b->pool, "textdelta-chunk", "cs",
+  return svn_ra_svn_write_templated_cmd(b->conn, b->pool, svn_ra_svn_cmd_textdelta_chunk,
                               b->token, &str);
 }
 
@@ -291,7 +291,7 @@ static svn_error_t *ra_svn_svndiff_close
   ra_svn_baton_t *b = baton;
 
   SVN_ERR(check_for_error(b->eb, b->pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, b->pool, "textdelta-end", "c",
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, b->pool, svn_ra_svn_cmd_textdelta_end,
                                b->token));
   return SVN_NO_ERROR;
 }
@@ -307,7 +307,7 @@ static svn_error_t *ra_svn_apply_textdel
 
   /* Tell the other side we're starting a text delta. */
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "apply-textdelta", "c(?c)",
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_apply_textdelta,
                                b->token, base_checksum));
 
   /* Transform the window stream to an svndiff stream.  Reuse the
@@ -337,7 +337,7 @@ static svn_error_t *ra_svn_change_file_p
   ra_svn_baton_t *b = file_baton;
 
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "change-file-prop", "cc(?s)",
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_change_file_prop,
                                b->token, name, value));
   return SVN_NO_ERROR;
 }
@@ -349,7 +349,7 @@ static svn_error_t *ra_svn_close_file(vo
   ra_svn_baton_t *b = file_baton;
 
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "close-file", "c(?c)",
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_close_file,
                                b->token, text_checksum));
   return SVN_NO_ERROR;
 }
@@ -365,7 +365,7 @@ static svn_error_t *ra_svn_absent_file(c
     return SVN_NO_ERROR;
 
   SVN_ERR(check_for_error(b->eb, pool));
-  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "absent-file", "cc", path,
+  SVN_ERR(svn_ra_svn_write_templated_cmd(b->conn, pool, svn_ra_svn_cmd_absent_file, path,
                                b->token));
   return SVN_NO_ERROR;
 }
@@ -377,11 +377,11 @@ static svn_error_t *ra_svn_close_edit(vo
 
   SVN_ERR_ASSERT(!eb->got_status);
   eb->got_status = TRUE;
-  SVN_ERR(svn_ra_svn_write_cmd(eb->conn, pool, "close-edit", ""));
+  SVN_ERR(svn_ra_svn_write_templated_cmd(eb->conn, pool, svn_ra_svn_cmd_close_edit));
   err = svn_ra_svn_read_cmd_response(eb->conn, pool, "");
   if (err)
     {
-      svn_error_clear(svn_ra_svn_write_cmd(eb->conn, pool, "abort-edit", ""));
+      svn_error_clear(svn_ra_svn_write_templated_cmd(eb->conn, pool, svn_ra_svn_cmd_abort_edit));
       return err;
     }
   if (eb->callback)
@@ -395,7 +395,7 @@ static svn_error_t *ra_svn_abort_edit(vo
 
   if (eb->got_status)
     return SVN_NO_ERROR;
-  SVN_ERR(svn_ra_svn_write_cmd(eb->conn, pool, "abort-edit", ""));
+  SVN_ERR(svn_ra_svn_write_templated_cmd(eb->conn, pool, svn_ra_svn_cmd_abort_edit));
   SVN_ERR(svn_ra_svn_read_cmd_response(eb->conn, pool, ""));
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/10Gb/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/subversion/libsvn_ra_svn/marshal.c?rev=1388276&r1=1388275&r2=1388276&view=diff
==============================================================================
--- subversion/branches/10Gb/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/10Gb/subversion/libsvn_ra_svn/marshal.c Fri Sep 21 00:04:56 2012
@@ -581,13 +581,285 @@ svn_error_t *svn_ra_svn_flush(svn_ra_svn
 
 /* --- 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_start_list(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  return svn_ra_svn_start_list(conn, pool);
+}
+
+static svn_error_t *
+vwrite_tuple_end_list(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  return svn_ra_svn_end_list(conn, pool);
+}
+
+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 *
+vwrite_cmd_open_root(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_revision_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_delete_entry(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_revision_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_add_dir(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_revision_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_open_dir(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_revision_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_change_dir_prop(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_string_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_absent_dir(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_add_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_revision_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_open_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_revision_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_change_file_prop(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_string_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_close_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_absent_file(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_textdelta_chunk(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_string(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_apply_textdelta(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  SVN_ERR(vwrite_tuple_cstring(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_start_list(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_cstring_opt(conn, pool, ap));
+  SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+vwrite_cmd_no_op(svn_ra_svn_conn_t *conn, apr_pool_t *pool, va_list ap)
+{
+  return SVN_NO_ERROR;
+}
+
+typedef svn_error_t *
+(*vwrite_tuple_func)(svn_ra_svn_conn_t *, apr_pool_t *, va_list);
+
+typedef struct cmd_template_t
+{
+  const char *start_sequence;
+  apr_size_t start_sequence_length;
+  vwrite_tuple_func write_ops;
+} cmd_template_t;
+
+static const cmd_template_t cmd_templates[svn_ra_svn_cmd__last]
+    = { {"( target-rev ( "      , 15, vwrite_tuple_revision },
+        {"( open-root ( "       , 14, vwrite_cmd_open_root },
+        {"( delete-entry ( "    , 17, vwrite_cmd_delete_entry },
+        {"( add-dir ( "         , 12, vwrite_cmd_add_dir },
+        {"( open-dir ( "        , 13, vwrite_cmd_open_dir },
+        {"( change-dir-prop ( " , 20, vwrite_cmd_change_dir_prop },
+        {"( close-dir ( "       , 14, vwrite_tuple_cstring },
+        {"( absent-dir ( "      , 15, vwrite_cmd_absent_dir },
+        {"( add-file ( "        , 13, vwrite_cmd_add_file },
+        {"( open-file ( "       , 14, vwrite_cmd_open_file },
+        {"( change-file-prop ( ", 21, vwrite_cmd_change_file_prop },
+        {"( close-file ( "      , 15, vwrite_cmd_close_file },
+        {"( absent-file ( "     , 16, vwrite_cmd_absent_file },
+        {"( textdelta-chunk ( " , 20, vwrite_cmd_textdelta_chunk },
+        {"( textdelta-end ( "   , 18, vwrite_tuple_cstring },
+        {"( apply-textdelta ( " , 20, vwrite_cmd_apply_textdelta },
+        {"( close-edit ( "      , 15, vwrite_cmd_no_op },
+        {"( abort-edit ( "      , 15, vwrite_cmd_no_op }
+      };
+
+
 static svn_error_t *vwrite_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                  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++;
@@ -596,53 +868,30 @@ static svn_error_t *vwrite_tuple(svn_ra_
   for (; *fmt; fmt++)
     {
       if (*fmt == 'c')
-        {
-          cstr = va_arg(ap, const char *);
-          if (cstr)
-            SVN_ERR(svn_ra_svn_write_cstring(conn, pool, cstr));
-          else
-            SVN_ERR_ASSERT(opt);
-        }
+        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 *);
-          if (str)
-            SVN_ERR(svn_ra_svn_write_string(conn, pool, str));
-          else
-            SVN_ERR_ASSERT(opt);
-        }
+        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(vwrite_tuple_start_list(conn, pool, ap));
       else if (*fmt == ')')
         {
-          SVN_ERR(svn_ra_svn_end_list(conn, pool));
+          SVN_ERR(vwrite_tuple_end_list(conn, pool, ap));
           opt = FALSE;
         }
       else if (*fmt == '?')
         opt = TRUE;
       else if (*fmt == 'w')
-        {
-          cstr = va_arg(ap, const char *);
-          if (cstr)
-            SVN_ERR(svn_ra_svn_write_word(conn, pool, cstr));
-          else
-            SVN_ERR_ASSERT(opt);
-        }
+        SVN_ERR(opt ? vwrite_tuple_word_opt(conn, pool, ap)
+                    : vwrite_tuple_word(conn, pool, ap));
       else if (*fmt == 'r')
-        {
-          rev = va_arg(ap, svn_revnum_t);
-          if (SVN_IS_VALID_REVNUM(rev))
-            SVN_ERR(svn_ra_svn_write_number(conn, pool, rev));
-          else
-            SVN_ERR_ASSERT(opt);
-        }
+        SVN_ERR(opt ? vwrite_tuple_revision_opt(conn, pool, ap)
+                    : vwrite_tuple_revision(conn, pool, ap));
       else if (*fmt == 'n' && !opt)
-        SVN_ERR(svn_ra_svn_write_number(conn, pool, va_arg(ap, apr_uint64_t)));
+        SVN_ERR(vwrite_tuple_number(conn, pool, ap));
       else if (*fmt == 'b' && !opt)
-        {
-          cstr = va_arg(ap, svn_boolean_t) ? "true" : "false";
-          SVN_ERR(svn_ra_svn_write_word(conn, pool, cstr));
-        }
+        SVN_ERR(vwrite_tuple_boolean(conn, pool, ap));
       else if (*fmt == '!' && !*(fmt + 1))
         return SVN_NO_ERROR;
       else
@@ -1172,6 +1421,23 @@ svn_error_t *svn_ra_svn_write_cmd(svn_ra
   return err ? svn_error_trace(err) : svn_ra_svn_end_list(conn, pool);
 }
 
+svn_error_t *svn_ra_svn_write_templated_cmd(svn_ra_svn_conn_t *conn,
+                                            apr_pool_t *pool,
+                                            svn_ra_svn_cmd_t cmd, ...)
+{
+  va_list ap;
+  svn_error_t *err;
+
+  SVN_ERR(writebuf_write_short_string(conn, pool,
+                                      cmd_templates[cmd].start_sequence,
+                                      cmd_templates[cmd].start_sequence_length));
+  va_start(ap, cmd);
+  err = cmd_templates[cmd].write_ops(conn, pool, ap);
+  va_end(ap);
+
+  return err ? err : writebuf_write_short_string(conn, pool, ") ) ", 4);
+}
+
 svn_error_t *svn_ra_svn_write_cmd_response(svn_ra_svn_conn_t *conn,
                                            apr_pool_t *pool,
                                            const char *fmt, ...)



Mime
View raw message