git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH 18/21] strbuf: allow "buf" to point to the middle of the allocated buffer
Date: Wed, 15 Dec 2010 22:02:53 +0700	[thread overview]
Message-ID: <1292425376-14550-19-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1292425376-14550-1-git-send-email-pclouds@gmail.com>

This allows offseting buf forward by neglen bytes. This patch makes
sure that reallocation works even when buf is not at the top of
allocated region.

Many functions are not aware that there could be data before buf. Use
with care.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 strbuf.c |   36 ++++++++++++++++++++++++++----------
 strbuf.h |   10 ++++++----
 2 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/strbuf.c b/strbuf.c
index bc3a080..12cda6f 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -28,8 +28,10 @@ char strbuf_slopbuf[1];
 
 void strbuf_init(struct strbuf *sb, size_t hint)
 {
-	sb->alloc = sb->len = 0;
-	sb->buf = strbuf_slopbuf;
+	sb->alloc  = 0;
+	sb->len	   = 0;
+	sb->neglen = 0;
+	sb->buf	   = strbuf_slopbuf;
 	if (hint)
 		strbuf_grow(sb, hint);
 }
@@ -37,7 +39,7 @@ void strbuf_init(struct strbuf *sb, size_t hint)
 void strbuf_release(struct strbuf *sb)
 {
 	if (sb->alloc) {
-		free(sb->buf);
+		free(sb->buf - sb->neglen);
 		strbuf_init(sb, 0);
 	}
 }
@@ -45,6 +47,8 @@ void strbuf_release(struct strbuf *sb)
 char *strbuf_detach(struct strbuf *sb, size_t *sz)
 {
 	char *res = sb->alloc ? sb->buf : NULL;
+	if (sb->neglen)
+		die("shift buf back before detaching");
 	if (sz)
 		*sz = sb->len;
 	strbuf_init(sb, 0);
@@ -54,20 +58,23 @@ char *strbuf_detach(struct strbuf *sb, size_t *sz)
 void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
 {
 	strbuf_release(sb);
-	sb->buf   = buf;
-	sb->len   = len;
-	sb->alloc = alloc;
+	sb->buf    = buf;
+	sb->len    = len;
+	sb->neglen = 0;
+	sb->alloc  = alloc;
 	strbuf_grow(sb, 0);
 	sb->buf[sb->len] = '\0';
 }
 
 void strbuf_grow(struct strbuf *sb, size_t extra)
 {
-	if (sb->len + extra + 1 <= sb->len)
+	char *buf = !sb->alloc ? NULL : sb->buf - sb->neglen;
+	int len = sb->neglen + sb->len;
+
+	if (len + extra + 1 <= len)
 		die("you want to use way too much memory");
-	if (!sb->alloc)
-		sb->buf = NULL;
-	ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
+	ALLOC_GROW(buf, len + extra + 1, sb->alloc);
+	sb->buf = buf + sb->neglen;
 }
 
 void strbuf_trim(struct strbuf *sb)
@@ -402,3 +409,12 @@ int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
 	strbuf_splice(sb, 0, 0, "refs/heads/", 11);
 	return check_ref_format(sb->buf);
 }
+
+void strbuf_offset(struct strbuf *sb, int offset)
+{
+	if (offset > sb->len || offset < sb->neglen)
+		die("you cannot offset out of allocated buffer");
+	sb->buf	   += offset;
+	sb->neglen += offset;
+	sb->len	   -= offset;
+}
diff --git a/strbuf.h b/strbuf.h
index fac2dbc..3c3b146 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -43,11 +43,11 @@
 extern char strbuf_slopbuf[];
 struct strbuf {
 	size_t alloc;
-	size_t len;
+	size_t len, neglen;
 	char *buf;
 };
 
-#define STRBUF_INIT  { 0, 0, strbuf_slopbuf }
+#define STRBUF_INIT  { 0, 0, 0, strbuf_slopbuf }
 
 /*----- strbuf life cycle -----*/
 extern void strbuf_init(struct strbuf *, size_t);
@@ -62,7 +62,7 @@ static inline void strbuf_swap(struct strbuf *a, struct strbuf *b) {
 
 /*----- strbuf size related -----*/
 static inline size_t strbuf_avail(const struct strbuf *sb) {
-	return sb->alloc ? sb->alloc - sb->len - 1 : 0;
+	return sb->alloc ? sb->alloc - sb->len - sb->neglen - 1 : 0;
 }
 
 extern void strbuf_grow(struct strbuf *, size_t);
@@ -70,7 +70,7 @@ extern void strbuf_grow(struct strbuf *, size_t);
 static inline void strbuf_setlen(struct strbuf *sb, size_t len) {
 	if (!sb->alloc)
 		strbuf_grow(sb, 0);
-	assert(len < sb->alloc);
+	assert(sb->neglen + len < sb->alloc);
 	sb->len = len;
 	sb->buf[len] = '\0';
 }
@@ -136,4 +136,6 @@ extern int launch_editor(const char *path, struct strbuf *buffer, const char *co
 extern int strbuf_branchname(struct strbuf *sb, const char *name);
 extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name);
 
+extern void strbuf_offset(struct strbuf *sb, int offset);
+
 #endif /* STRBUF_H */
-- 
1.7.3.3.476.g10a82

  parent reply	other threads:[~2010-12-15 15:06 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-15 15:02 [PATCH 00/21] nd/struct-pathspec v2 Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 01/21] Add struct pathspec Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 02/21] diff-no-index: use diff_tree_setup_paths() Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 03/21] Convert struct diff_options to use struct pathspec Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 04/21] tree_entry_interesting(): remove dependency on struct diff_options Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 05/21] Move tree_entry_interesting() to tree-walk.c and export it Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 06/21] glossary: define pathspec Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 07/21] diff-tree: convert base+baselen to writable strbuf Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 08/21] tree_entry_interesting(): refactor into separate smaller functions Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 09/21] tree_entry_interesting(): support depth limit Nguyễn Thái Ngọc Duy
2011-01-28 20:40   ` Junio C Hamano
2011-01-29  3:13     ` Nguyen Thai Ngoc Duy
2011-01-31 20:21       ` [PATCH] tree_entry_interesting(): with no pathspecs, everything will match Junio C Hamano
2010-12-15 15:02 ` [PATCH 10/21] tree_entry_interesting(): fix depth limit with overlapping pathspecs Nguyễn Thái Ngọc Duy
2010-12-16 23:31   ` Junio C Hamano
2010-12-17 10:05     ` Nguyen Thai Ngoc Duy
2010-12-17 20:02       ` Junio C Hamano
2010-12-18  3:37     ` Nguyen Thai Ngoc Duy
2010-12-15 15:02 ` [PATCH 11/21] tree_entry_interesting(): support wildcard matching Nguyễn Thái Ngọc Duy
2019-02-04 10:36   ` [PATCH] diff-tree doc: correct & remove wrong documentation Ævar Arnfjörð Bjarmason
2019-02-04 10:42     ` Duy Nguyen
2019-02-04 21:10     ` Junio C Hamano
2019-02-04 21:49       ` Ævar Arnfjörð Bjarmason
2010-12-15 15:02 ` [PATCH 12/21] tree_entry_interesting(): optimize wildcard matching when base is matched Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 13/21] pathspec: add match_pathspec_depth() Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 14/21] Convert ce_path_match() to use struct pathspec Nguyễn Thái Ngọc Duy
2010-12-17  0:02   ` Junio C Hamano
2010-12-17  9:59     ` Nguyen Thai Ngoc Duy
2010-12-17 12:43       ` [PATCH 14/21] struct rev_info: convert prune_data to " Nguyễn Thái Ngọc Duy
2010-12-17 12:43         ` [PATCH 15/21] Convert ce_path_match() to use " Nguyễn Thái Ngọc Duy
2010-12-17 15:09       ` [PATCH 14/21] " Junio C Hamano
2010-12-17 15:11         ` Nguyen Thai Ngoc Duy
2010-12-17 20:29           ` Junio C Hamano
2010-12-15 15:02 ` [PATCH 15/21] Convert ce_path_match() to use match_pathspec_depth() Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 16/21] grep: convert to use struct pathspec Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 17/21] grep: use match_pathspec_depth() for cache/worktree grepping Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` Nguyễn Thái Ngọc Duy [this message]
2010-12-15 15:02 ` [PATCH 19/21] grep: use writable strbuf from caller in grep_tree() Nguyễn Thái Ngọc Duy
2010-12-17  0:15   ` Junio C Hamano
2010-12-17  9:56     ` Nguyen Thai Ngoc Duy
2010-12-17 12:44       ` [PATCH 19/21] grep: use writable strbuf from caller for grep_tree() Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 20/21] grep: drop pathspec_matches() in favor of tree_entry_interesting() Nguyễn Thái Ngọc Duy
2010-12-17 12:45   ` Nguyễn Thái Ngọc Duy
2010-12-15 15:02 ` [PATCH 21/21] t7810: overlapping pathspecs and depth limit Nguyễn Thái Ngọc Duy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1292425376-14550-19-git-send-email-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).