summaryrefslogtreecommitdiff
path: root/src/bin/sb.c
diff options
context:
space:
mode:
authorBoris Faure <billiob@gmail.com>2016-11-06 19:44:35 +0100
committerBoris Faure <billiob@gmail.com>2016-11-06 19:45:05 +0100
commitc41fc2a56e5da4a07ea693ad5c55fea86101119c (patch)
treeefdcb9df22848ccd33d036f15f4905e79362ff88 /src/bin/sb.c
parentdab654c2786cabb563b9acedd1d4db6bf690f8fd (diff)
sb: add some utilities like prepend, free, steal…
Diffstat (limited to 'src/bin/sb.c')
-rw-r--r--src/bin/sb.c87
1 files changed, 83 insertions, 4 deletions
diff --git a/src/bin/sb.c b/src/bin/sb.c
index e780b36..939c2b3 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)
10{ 10{
11 size_t new_len = sb->len + len; 11 size_t new_len = sb->len + len;
12 12
13 if ((new_len >= sb->alloc) || !sb->buf) 13 if ((new_len + sb->gap >= sb->alloc) || !sb->buf)
14 { 14 {
15 size_t new_alloc = ((new_len + 15) / 16) * 24; 15 size_t new_alloc = ((new_len + sb->gap + 15) / 16) * 24;
16 char *new_buf; 16 char *new_buf;
17 17
18 new_buf = realloc(sb->buf, new_alloc); 18 new_buf = realloc(sb->buf - sb->gap, new_alloc);
19 if (new_buf == NULL) 19 if (new_buf == NULL)
20 return -1; 20 return -1;
21 sb->buf = new_buf; 21 sb->buf = new_buf + sb->gap;
22 sb->alloc = new_alloc; 22 sb->alloc = new_alloc;
23 } 23 }
24 memcpy(sb->buf + sb->len, s, len); 24 memcpy(sb->buf + sb->len, s, len);
@@ -27,6 +27,35 @@ ty_sb_add(struct ty_sb *sb, const char *s, size_t len)
27 return 0; 27 return 0;
28} 28}
29 29
30int
31ty_sb_prepend(struct ty_sb *sb, const char *s, size_t len)
32{
33 if (len >= sb->gap)
34 {
35 size_t aligned_gap = ((len + 15) / 16) * 24;
36 size_t third_of_alloc = (((sb->alloc / 3) + 15) / 16) * 16;
37 size_t new_gap = MAX(aligned_gap, third_of_alloc);
38 size_t new_alloc = sb->alloc + new_gap;
39 char *new_buf;
40
41 new_buf = calloc(new_alloc, 1);
42 if (new_buf == NULL)
43 return -1;
44
45 memcpy(new_buf + new_gap, sb->buf, sb->len);
46 sb->buf = new_buf + new_gap;
47 sb->gap = new_gap;
48 sb->alloc = new_alloc;
49 }
50
51 sb->buf -= len;
52 sb->gap -= len;
53 sb->len += len;
54 memcpy(sb->buf, s, len);
55 return 0;
56}
57
58
30/* unlike eina_strbuf_rtrim, only trims \t, \f, ' ' */ 59/* unlike eina_strbuf_rtrim, only trims \t, \f, ' ' */
31void 60void
32ty_sb_spaces_rtrim(struct ty_sb *sb) 61ty_sb_spaces_rtrim(struct ty_sb *sb)
@@ -43,3 +72,53 @@ ty_sb_spaces_rtrim(struct ty_sb *sb)
43 } 72 }
44 sb->buf[sb->len] = '\0'; 73 sb->buf[sb->len] = '\0';
45} 74}
75
76char *
77ty_sb_steal_buf(struct ty_sb *sb)
78{
79 size_t i;
80 char *buf;
81
82 if (sb->gap != 0)
83 {
84 sb->buf -= sb->gap;
85 for (i = 0; i <= sb->len; i++)
86 {
87 sb->buf[i] = sb->buf[i + sb->gap];
88 }
89 sb->gap = 0;
90 }
91
92 sb->alloc = 0;
93 sb->gap = 0;
94 sb->len = 0;
95
96 buf = sb->buf;
97
98 sb->buf = NULL;
99
100 return buf;
101}
102
103void
104ty_sb_lskip(struct ty_sb *sb, int len)
105{
106 sb->len -= len;
107 sb->gap += len;
108 sb->buf += len;
109}
110
111void
112ty_sb_rskip(struct ty_sb *sb, int len)
113{
114 sb->len -= len;
115 sb->buf[sb->len] = '\0';
116}
117
118void
119ty_sb_free(struct ty_sb *sb)
120{
121 free(sb->buf - sb->gap);
122 sb->gap = sb->len = sb->alloc = 0;
123 sb->buf = NULL;
124}