git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 7/9] Implement file-related functions

From
Ramkumar Ramachandra <artagnon@gmail.com>
Date
Jul 13, 2010, 23:36 UTC
Message-ID
<1279064176-6645-8-git-send-email-artagnon@gmail.com>
In-Reply-To
<1279064176-6645-1-git-send-email-artagnon@gmail.com>

Implement add_file, open_file and change_file_prop. All of them involve dumping the corresponding node information and setting up the file_baton for apply_textdelta and close_file to use.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 dump_editor.c |  127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 dumpr_util.h  |   15 +++++++
 2 files changed, 138 insertions(+), 4 deletions(-)
diff --git a/dump_editor.c b/dump_editor.c
index 7fafa8b..8b0a830 100644
--- a/dump_editor.c
+++ b/dump_editor.c
@@ -342,7 +342,34 @@ static svn_error_t *add_file(const char *path,
 			     apr_pool_t *pool,
 			     void **file_baton)
 {
-	*file_baton = NULL;
+	struct dir_baton *pb = parent_baton;
+	void *val;
+
+	/* Some pending properties to dump? */
+	SVN_ERR(dump_props(pb->eb, &(pb->eb->dump_props_pending), TRUE, pool));
+
+	/* This might be a replacement -- is the path already deleted? */
+	val = apr_hash_get(pb->deleted_entries, path, APR_HASH_KEY_STRING);
+
+	/* Detect add-with-history. */
+	pb->eb->is_copy = ARE_VALID_COPY_ARGS(copyfrom_path, copyfrom_rev);
+
+	/* Dump the node. */
+	SVN_ERR(dump_node(pb->eb, path,
+	                  svn_node_file,
+	                  val ? svn_node_action_replace : svn_node_action_add,
+	                  pb->eb->is_copy ? copyfrom_path : NULL,
+	                  pb->eb->is_copy ? copyfrom_rev : SVN_INVALID_REVNUM,
+	                  pool));
+
+	if (val)
+		/* delete the path, it's now been dumped. */
+		apr_hash_set(pb->deleted_entries, path, APR_HASH_KEY_STRING, NULL);
+
+	/* Build a nice file baton to pass to change_file_prop and apply_textdelta */
+	pb->eb->changed_path = path;
+	*file_baton = pb->eb;
+
 	return SVN_NO_ERROR;
 }
 
@@ -352,7 +379,31 @@ static svn_error_t *open_file(const char *path,
 			      apr_pool_t *pool,
 			      void **file_baton)
 {
-	*file_baton = NULL;
+	struct dir_baton *pb = parent_baton;
+	const char *cmp_path = NULL;
+	svn_revnum_t cmp_rev = SVN_INVALID_REVNUM;
+
+	/* Some pending properties to dump? */
+	SVN_ERR(dump_props(pb->eb, &(pb->eb->dump_props_pending), TRUE, pool));
+
+	apr_array_header_t *compose_path = apr_array_make(pool, 2, sizeof(const char *));
+	/* If the parent directory has explicit comparison path and rev,
+	   record the same for this one. */
+	if (pb && ARE_VALID_COPY_ARGS(pb->cmp_path, pb->cmp_rev)) {
+		APR_ARRAY_PUSH(compose_path, const char *) = pb->cmp_path;
+		APR_ARRAY_PUSH(compose_path, const char *) = svn_relpath_basename(path, pool);
+		cmp_path = svn_path_compose(compose_path, pool);
+		cmp_rev = pb->cmp_rev;
+	}
+
+	SVN_ERR(dump_node(pb->eb, path,
+	                  svn_node_file, svn_node_action_change,
+	                  cmp_path, cmp_rev, pool));
+
+	/* Build a nice file baton to pass to change_file_prop and apply_textdelta */
+	pb->eb->changed_path = path;
+	*file_baton = pb->eb;
+
 	return SVN_NO_ERROR;
 }
 
@@ -397,6 +448,44 @@ static svn_error_t *change_file_prop(void *file_baton,
 				     const svn_string_t *value,
 				     apr_pool_t *pool)
 {
+	struct dump_edit_baton *eb = file_baton;
+
+	if (svn_property_kind(NULL, name) != svn_prop_regular_kind)
+		return SVN_NO_ERROR;
+
+	apr_hash_set(eb->properties, apr_pstrdup(pool, name),
+		     APR_HASH_KEY_STRING, value ?
+		     svn_string_dup(value, pool): (void *)0x1);
+
+	/* Dump the property headers and wait; close_file might need
+	   to write text headers too depending on whether
+	   apply_textdelta is called */
+	eb->dump_props_pending = TRUE;
+
+	return SVN_NO_ERROR;
+}
+
+static svn_error_t *window_handler(svn_txdelta_window_t *window, void *baton)
+{
+	struct handler_baton *hb = baton;
+	struct dump_edit_baton *eb = hb->eb;
+	static svn_error_t *err;
+
+	err = hb->apply_handler(window, hb->apply_baton);
+	if (window != NULL && !err)
+		return SVN_NO_ERROR;
+
+	if (err)
+		SVN_ERR(err);
+
+	/* Write information about the filepath to hb->eb */
+	eb->temp_filepath = apr_pstrdup(eb->pool,
+					hb->temp_filepath);
+
+	/* Cleanup */
+	SVN_ERR(svn_io_file_close(hb->temp_file, hb->pool));
+	SVN_ERR(svn_stream_close(hb->temp_filestream));
+	svn_pool_destroy(hb->pool);
 	return SVN_NO_ERROR;
 }
 
@@ -405,8 +494,38 @@ static svn_error_t *apply_textdelta(void *file_baton, const char *base_checksum,
 				    svn_txdelta_window_handler_t *handler,
 				    void **handler_baton)
 {
-	*handler = svn_delta_noop_window_handler;
-	*handler_baton = NULL;
+	struct dump_edit_baton *eb = file_baton;
+	apr_status_t apr_err;
+	const char *tempdir;
+
+	/* Custom handler_baton allocated in a separate pool */
+	apr_pool_t *handler_pool = svn_pool_create(pool);
+	struct handler_baton *hb = apr_pcalloc(handler_pool, sizeof(*hb));
+	hb->pool = handler_pool;
+	hb->eb = eb;
+
+	/* Use a temporary file to measure the text-content-length */
+	SVN_ERR(svn_io_temp_dir(&tempdir, hb->pool));
+
+	hb->temp_filepath = svn_dirent_join(tempdir, "XXXXXX", hb->pool);
+	apr_err = apr_file_mktemp(&(hb->temp_file), hb->temp_filepath,
+				  APR_CREATE | APR_READ | APR_WRITE | APR_EXCL,
+				  hb->pool);
+	if (apr_err != APR_SUCCESS)
+		SVN_ERR(svn_error_wrap_apr(apr_err, NULL));
+
+	hb->temp_filestream = svn_stream_from_aprfile2(hb->temp_file, TRUE, hb->pool);
+
+	/* Prepare to write the delta to the temporary file */
+	svn_txdelta_to_svndiff2(&(hb->apply_handler), &(hb->apply_baton),
+	                        hb->temp_filestream, 0, hb->pool);
+	eb->must_dump_text = TRUE;
+
+	/* The actual writing takes place when this function has finished */
+	/* Set the handler and handler_baton */
+	*handler = window_handler;
+	*handler_baton = hb;
+
 	return SVN_NO_ERROR;
 }
 
diff --git a/dumpr_util.h b/dumpr_util.h
index 4b0d5b0..9870b0d 100644
--- a/dumpr_util.h
+++ b/dumpr_util.h
@@ -64,6 +64,21 @@ struct dir_baton {
 	apr_pool_t *pool;
 };
 
+struct handler_baton
+{
+	svn_txdelta_window_handler_t apply_handler;
+	void *apply_baton;
+	apr_pool_t *pool;
+
+	/* Information about the path of the tempoarary file used */
+	char *temp_filepath;
+	apr_file_t *temp_file;
+	svn_stream_t *temp_filestream;
+
+	/* To fill in the edit baton fields */
+	struct dump_edit_baton *eb;
+};
+
 void write_hash_to_stringbuf(apr_hash_t *properties,
 			     svn_boolean_t deleted,
 			     svn_stringbuf_t **strbuf,
-- 
1.7.1
Previous: Ramkumar RamachandraNext: Ramkumar Ramachandra
Message 10 of 26 in “Get svnrdump merged into git.git”
  1. 0/9 Get svnrdump merged into git.gitRamkumar Ramachandra, Jul 13, 2010
  2. 1/9 Add LICENSERamkumar Ramachandra, Jul 13, 2010
  3. Daniel ShahafJul 14, 2010
  4. Ramkumar RamachandraJul 14, 2010
  5. 2/9 Add skeleton SVN client and MakefileRamkumar Ramachandra, Jul 13, 2010
  6. 3/9 Add debug editor from Subversion trunkRamkumar Ramachandra, Jul 13, 2010
  7. 4/9 Drive the debug editorRamkumar Ramachandra, Jul 13, 2010
  8. 5/9 Dump the revprops at the start of every revisionRamkumar Ramachandra, Jul 13, 2010
  9. 6/9 Implement directory-related functionsRamkumar Ramachandra, Jul 13, 2010
  10. 7/9 Implement file-related functionsRamkumar Ramachandra, Jul 13, 2010
  11. 8/9 Implement close_fileRamkumar Ramachandra, Jul 13, 2010
  12. 9/9 Add a validation scriptRamkumar Ramachandra, Jul 13, 2010
  13. Ramkumar RamachandraJul 13, 2010
  14. Jonathan NiederJul 14, 2010
  15. Ramkumar RamachandraJul 14, 2010
  16. Jonathan NiederJul 14, 2010
  17. Ramkumar RamachandraJul 14, 2010
  18. Stefan SperlingJul 14, 2010
  19. Ramkumar RamachandraJul 14, 2010
  20. Stefan SperlingJul 14, 2010
  21. Junio C HamanoJul 14, 2010
  22. Ramkumar RamachandraJul 15, 2010
  23. Jonathan NiederAug 6, 2010
  24. Jonathan NiederAug 7, 2010
  25. Ramkumar RamachandraAug 7, 2010
  26. Ramkumar RamachandraAug 7, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.