[PATCH 5 of 6 RFC hglib] hg_fetch_cset_entry: will get, parse and pass changesets to user

Iulian Stana julian.stana at gmail.com
Thu Sep 5 09:13:25 CDT 2013


# HG changeset patch
# User Iulian Stana <julian.stana at gmail.com>
# Date 1378389265 -10800
#      Thu Sep 05 16:54:25 2013 +0300
# Node ID 45ab6314f20f386125e15e369cd1b719e3e7ebf2
# Parent  17d04670c65d6e6653a7a3c7875f2918abe073c3
hg_fetch_cset_entry: will get, parse and pass changesets to user

diff --git a/client.c b/client.c
--- a/client.c
+++ b/client.c
@@ -105,3 +105,60 @@
 	}
 	return exitcode;
 }
+
+
+/* The cbuf next step. Getting the next changeset. */
+int hg_fetch_cset_entry(hg_csetstream_buffer *cbuf, hg_cset_entry *centry)
+{
+	hg_header head;
+	int exitcode, bc;
+	char *get_data;
+
+	/* Erase the first cset from cset pointer.
+	 * This cset was already pass to user.*/
+	if(cbuf->buf_size){
+		cbuf->buf_size = erase_cset(&cbuf->buffer, cbuf->buf_size,
+						cbuf->first_cset_size);
+	}
+
+	while(!detect_null_byte(cbuf->buffer + 1, cbuf->buf_size, 1))
+	{
+		head = hg_head(cbuf->handle);
+		if(head.channel == 'r')
+			break;
+		/* if there is any error, read everything from pipe:
+		 *    pass error data to callback function
+		 *    trash the output data
+		 *    read the exticode 
+		 *    return -1;
+		 **/
+		else if(head.channel == 'e'){
+			trash_data(cbuf->handle, cbuf->callback);
+			return -1;
+		}
+
+		get_data = malloc(head.length + 1);
+		if(bc = hg_rawread(cbuf->handle, get_data, head.length), bc < 0)
+			return -1;
+		append_data(&cbuf->buffer, get_data, cbuf->buf_size, bc);
+		cbuf->buf_size += bc;
+		free(get_data);
+	}
+	
+	if(bc = detect_null_byte(cbuf->buffer + 1, cbuf->buf_size, 0), bc > 0){
+		cbuf->first_cset_size = bc + 1;
+		parse_changeset(cbuf->buffer + 1, centry);
+		return 1;
+	/* Parse first cset from the remaining data. */
+	}
+
+	exitcode = hg_exitcode(cbuf->handle);
+	free(cbuf->command);
+	free(cbuf->buffer);
+	free(cbuf);
+	if(exitcode)
+		return -1;
+	return 0;
+
+}
+
diff --git a/client.h b/client.h
--- a/client.h
+++ b/client.h
@@ -49,4 +49,35 @@
 hg_csetstream_buffer *hg_log(hg_handle *handle, int (*callback)(const char *msg,
 						size_t len), char *argument[]);
 
+/**
+ * \brief The iterator step. Getting the next changeset.
+ *
+ * The revision history could have a huge mass of data. You cannot pass the 
+ * entire  history in one call, so we use an iterator-like mechanism. Calling 
+ * the hg_fetch_log_entry. The next changeset will be read from cmd-server, 
+ * parse and pass to hg_cset_entry structure.
+ * The cset_entry structure will handle a changeset with the following string 
+ * fields:
+ *         - rev
+ *         - node
+ *         - tags (space delimited)
+ *         - branch
+ *         - author
+ *         - desc
+ *
+ * \param hg_csetstream_buffer The buffer structure to store cset data.
+ * \param centry The hg_cset_entry structure where the changeset will be stored
+ *               and pass
+ * \retval 1  Succesful operation, pass the first find cset to centry structure
+ * \retval 0  To indicate the end of log_command, everything works well.
+ * \retval -1 to indicate an error, with errno set appropriately.
+ *
+ * errno can be:
+ *      - EINVAL  - Invalid argument (handle it's set to a null pointer)
+ *      - read(2) command errors
+ *      - read_header error
+ * */
+int hg_fetch_cset_entry(hg_csetstream_buffer *cbuf, hg_cset_entry *centry);
+
+
 #endif


More information about the Mercurial-devel mailing list