From c41fc2a56e5da4a07ea693ad5c55fea86101119c Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Sun, 6 Nov 2016 19:44:35 +0100 Subject: [PATCH] =?UTF-8?q?sb:=20add=20some=20utilities=20like=20prepend,?= =?UTF-8?q?=20free,=20steal=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/bin/sb.c | 87 +++++++++++++++++++++++++++++++++++++++++++++--- src/bin/sb.h | 12 ++++--- src/bin/termio.c | 5 +-- 3 files changed, 94 insertions(+), 10 deletions(-) diff --git a/src/bin/sb.c b/src/bin/sb.c index e780b36e..939c2b33 100644 --- a/src/bin/sb.c +++ b/src/bin/sb.c @@ -10,15 +10,15 @@ ty_sb_add(struct ty_sb *sb, const char *s, size_t len) { size_t new_len = sb->len + len; - if ((new_len >= sb->alloc) || !sb->buf) + if ((new_len + sb->gap >= sb->alloc) || !sb->buf) { - size_t new_alloc = ((new_len + 15) / 16) * 24; + size_t new_alloc = ((new_len + sb->gap + 15) / 16) * 24; char *new_buf; - new_buf = realloc(sb->buf, new_alloc); + new_buf = realloc(sb->buf - sb->gap, new_alloc); if (new_buf == NULL) return -1; - sb->buf = new_buf; + sb->buf = new_buf + sb->gap; sb->alloc = new_alloc; } memcpy(sb->buf + sb->len, s, len); @@ -27,6 +27,35 @@ ty_sb_add(struct ty_sb *sb, const char *s, size_t len) return 0; } +int +ty_sb_prepend(struct ty_sb *sb, const char *s, size_t len) +{ + if (len >= sb->gap) + { + size_t aligned_gap = ((len + 15) / 16) * 24; + size_t third_of_alloc = (((sb->alloc / 3) + 15) / 16) * 16; + size_t new_gap = MAX(aligned_gap, third_of_alloc); + size_t new_alloc = sb->alloc + new_gap; + char *new_buf; + + new_buf = calloc(new_alloc, 1); + if (new_buf == NULL) + return -1; + + memcpy(new_buf + new_gap, sb->buf, sb->len); + sb->buf = new_buf + new_gap; + sb->gap = new_gap; + sb->alloc = new_alloc; + } + + sb->buf -= len; + sb->gap -= len; + sb->len += len; + memcpy(sb->buf, s, len); + return 0; +} + + /* unlike eina_strbuf_rtrim, only trims \t, \f, ' ' */ void ty_sb_spaces_rtrim(struct ty_sb *sb) @@ -43,3 +72,53 @@ ty_sb_spaces_rtrim(struct ty_sb *sb) } sb->buf[sb->len] = '\0'; } + +char * +ty_sb_steal_buf(struct ty_sb *sb) +{ + size_t i; + char *buf; + + if (sb->gap != 0) + { + sb->buf -= sb->gap; + for (i = 0; i <= sb->len; i++) + { + sb->buf[i] = sb->buf[i + sb->gap]; + } + sb->gap = 0; + } + + sb->alloc = 0; + sb->gap = 0; + sb->len = 0; + + buf = sb->buf; + + sb->buf = NULL; + + return buf; +} + +void +ty_sb_lskip(struct ty_sb *sb, int len) +{ + sb->len -= len; + sb->gap += len; + sb->buf += len; +} + +void +ty_sb_rskip(struct ty_sb *sb, int len) +{ + sb->len -= len; + sb->buf[sb->len] = '\0'; +} + +void +ty_sb_free(struct ty_sb *sb) +{ + free(sb->buf - sb->gap); + sb->gap = sb->len = sb->alloc = 0; + sb->buf = NULL; +} diff --git a/src/bin/sb.h b/src/bin/sb.h index d504fe32..f52f775e 100644 --- a/src/bin/sb.h +++ b/src/bin/sb.h @@ -5,13 +5,17 @@ struct ty_sb { char *buf; + size_t gap; size_t len; size_t alloc; }; -int -ty_sb_add(struct ty_sb *sb, const char *s, size_t len); -void -ty_sb_spaces_rtrim(struct ty_sb *sb); +int ty_sb_add(struct ty_sb *sb, const char *s, size_t len); +void ty_sb_spaces_rtrim(struct ty_sb *sb); +int ty_sb_prepend(struct ty_sb *sb, const char *s, size_t len); +char *ty_sb_steal_buf(struct ty_sb *sb); +void ty_sb_lskip(struct ty_sb *sb, int len); +void ty_sb_rskip(struct ty_sb *sb, int len); +void ty_sb_free(struct ty_sb *sb); #endif diff --git a/src/bin/termio.c b/src/bin/termio.c index 8693c455..145655b0 100644 --- a/src/bin/termio.c +++ b/src/bin/termio.c @@ -2192,9 +2192,10 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, int c2x, int c2y, if (lenp) *lenp = sb.len; - return sb.buf; + return ty_sb_steal_buf(&sb); + err: - free(sb.buf); + ty_sb_free(&sb); return NULL; }