jcs
/amend
/amendments
/16
repo: Use BlockMove for overlapping data shift
This allows us to go back to using a single, expanded Handle when
shoving data into the TE.
Thanks to jjuran in #cyberpals for the tip
jcs made amendment 16 over 3 years ago
--- repo.c Mon Oct 18 17:12:17 2021
+++ repo.c Sat Oct 23 22:09:43 2021
@@ -331,7 +331,7 @@ repo_file_with_id(struct repo *repo, short id)
void
repo_show_diff_text(struct repo_commit *commit, TEHandle te)
{
- Handle diffh, allh;
+ Handle diffh;
TextStyle style;
struct tm *ttm = NULL;
char *buf;
@@ -386,33 +386,25 @@ repo_show_diff_text(struct repo_commit *commit, TEHand
all_len = MAX_TEXTEDIT_SIZE;
trunc = 1;
}
- allh = xNewHandle(all_len);
- /*
- * A more memory-efficient method would be:
- *
- * DetachResource(diffh);
- * SetHandleSize(diffh, all_len);
- * memmove(*diffh, *diffh + header_len, all_len - header_len);
- * memcpy(*diffh, buf, header_len);
- *
- * But memmove doesn't support overlapping buffers :/
- */
-
- HLock(allh);
- memcpy(*allh, buf, header_len);
+ DetachResource(diffh);
+ if (ResError())
+ err(1, "Failed detaching diff resource: %d", ResError());
+ SetHandleSize(diffh, all_len);
+ if (MemError())
+ err(1, "Failed resizing diff handle to %ul: %d", all_len,
+ MemError());
+ HLock(diffh);
+ BlockMove(*diffh, *diffh + header_len, all_len - header_len);
+ memcpy(*diffh, buf, header_len);
free(buf);
- HLock(diffh);
- memcpy(*allh + header_len, *diffh, all_len - header_len);
- ReleaseResource(diffh);
-
if (trunc) {
warn_off = MAX_TEXTEDIT_SIZE - header_len -
strlen(REPO_DIFF_TOO_BIG);
blen = sprintf(truncbuf, REPO_DIFF_TOO_BIG,
diff_len - warn_off);
- memcpy(*allh + MAX_TEXTEDIT_SIZE - blen, truncbuf, blen);
+ memcpy(*diffh + MAX_TEXTEDIT_SIZE - blen, truncbuf, blen);
}
TESetText("", 0, te);
@@ -423,7 +415,9 @@ repo_show_diff_text(struct repo_commit *commit, TEHand
style.tsFont = monaco;
style.tsSize = 9;
TESetStyle(doFont | doSize, &style, false, te);
- TEStylInsert(*allh, all_len, 0, te);
+ /* TODO: can we get away with just replacing te->hText with diffh? */
+ TEStylInsert(*diffh, all_len, 0, te);
+ DisposeHandle(diffh);
}
struct repo_file *