Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2015 Andrew Kelley
3 : : *
4 : : * This file is part of zig, which is MIT licensed.
5 : : * See http://opensource.org/licenses/MIT
6 : : */
7 : :
8 : : #ifndef ZIG_BUFFER_HPP
9 : : #define ZIG_BUFFER_HPP
10 : :
11 : : #include "list.hpp"
12 : :
13 : : #include <stdint.h>
14 : : #include <ctype.h>
15 : : #include <stdarg.h>
16 : :
17 : : #define BUF_INIT {{0}}
18 : :
19 : : // Note, you must call one of the alloc, init, or resize functions to have an
20 : : // initialized buffer. The assertions should help with this.
21 : : struct Buf {
22 : : ZigList<char> list;
23 : : };
24 : :
25 : : Buf *buf_sprintf(const char *format, ...)
26 : : ATTRIBUTE_PRINTF(1, 2);
27 : : Buf *buf_vprintf(const char *format, va_list ap);
28 : :
29 : 97919552 : static inline size_t buf_len(Buf *buf) {
30 : 97919552 : assert(buf);
31 : 97919552 : assert(buf->list.length);
32 : 97919552 : return buf->list.length - 1;
33 : : }
34 : :
35 : 50105097 : static inline char *buf_ptr(Buf *buf) {
36 : 50105097 : assert(buf);
37 : 50105097 : assert(buf->list.length);
38 : 50105097 : return buf->list.items;
39 : : }
40 : :
41 : 8751384 : static inline void buf_resize(Buf *buf, size_t new_len) {
42 : 8751384 : buf->list.resize(new_len + 1);
43 : 8751384 : buf->list.at(buf_len(buf)) = 0;
44 : 8751384 : }
45 : :
46 : 43108 : static inline Buf *buf_alloc_fixed(size_t size) {
47 : 43108 : Buf *buf = allocate<Buf>(1);
48 : 43108 : buf_resize(buf, size);
49 : 43108 : return buf;
50 : : }
51 : :
52 : 26920 : static inline Buf *buf_alloc(void) {
53 : 26920 : return buf_alloc_fixed(0);
54 : : }
55 : :
56 : 14001 : static inline void buf_deinit(Buf *buf) {
57 : 14001 : buf->list.deinit();
58 : 14001 : }
59 : :
60 : 552203 : static inline void buf_init_from_mem(Buf *buf, const char *ptr, size_t len) {
61 : 552203 : assert(len != SIZE_MAX);
62 : 552203 : buf->list.resize(len + 1);
63 : 552203 : memcpy(buf_ptr(buf), ptr, len);
64 : 552203 : buf->list.at(buf_len(buf)) = 0;
65 : 552203 : }
66 : :
67 : 19710 : static inline void buf_init_from_str(Buf *buf, const char *str) {
68 : 19710 : buf_init_from_mem(buf, str, strlen(str));
69 : 19710 : }
70 : :
71 : 337725 : static inline void buf_init_from_buf(Buf *buf, Buf *other) {
72 : 337725 : buf_init_from_mem(buf, buf_ptr(other), buf_len(other));
73 : 337725 : }
74 : :
75 : 179435 : static inline Buf *buf_create_from_mem(const char *ptr, size_t len) {
76 : 179435 : assert(len != SIZE_MAX);
77 : 179435 : Buf *buf = allocate<Buf>(1);
78 : 179435 : buf_init_from_mem(buf, ptr, len);
79 : 179435 : return buf;
80 : : }
81 : :
82 : 121460 : static inline Buf *buf_create_from_slice(Slice<uint8_t> slice) {
83 : 121460 : return buf_create_from_mem((const char *)slice.ptr, slice.len);
84 : : }
85 : :
86 : 50154 : static inline Buf *buf_create_from_str(const char *str) {
87 : 50154 : return buf_create_from_mem(str, strlen(str));
88 : : }
89 : :
90 : 7821 : static inline Buf *buf_create_from_buf(Buf *buf) {
91 : 7821 : return buf_create_from_mem(buf_ptr(buf), buf_len(buf));
92 : : }
93 : :
94 : 291 : static inline Buf *buf_slice(Buf *in_buf, size_t start, size_t end) {
95 : 291 : assert(in_buf->list.length);
96 : 291 : assert(start != SIZE_MAX);
97 : 291 : assert(end != SIZE_MAX);
98 : 291 : assert(start < buf_len(in_buf));
99 : 291 : assert(end <= buf_len(in_buf));
100 : 291 : Buf *out_buf = allocate<Buf>(1);
101 : 291 : out_buf->list.resize(end - start + 1);
102 : 291 : memcpy(buf_ptr(out_buf), buf_ptr(in_buf) + start, end - start);
103 : 291 : out_buf->list.at(buf_len(out_buf)) = 0;
104 : 291 : return out_buf;
105 : : }
106 : :
107 : 7369738 : static inline void buf_append_mem(Buf *buf, const char *mem, size_t mem_len) {
108 : 7369738 : assert(buf->list.length);
109 : 7369738 : assert(mem_len != SIZE_MAX);
110 : 7369738 : size_t old_len = buf_len(buf);
111 : 7369738 : buf_resize(buf, old_len + mem_len);
112 : 7369738 : memcpy(buf_ptr(buf) + old_len, mem, mem_len);
113 : 7369738 : buf->list.at(buf_len(buf)) = 0;
114 : 7369738 : }
115 : :
116 : 6309 : static inline void buf_append_str(Buf *buf, const char *str) {
117 : 6309 : assert(buf->list.length);
118 : 6309 : buf_append_mem(buf, str, strlen(str));
119 : 6309 : }
120 : :
121 : 44652 : static inline void buf_append_buf(Buf *buf, Buf *append_buf) {
122 : 44652 : assert(buf->list.length);
123 : 44652 : buf_append_mem(buf, buf_ptr(append_buf), buf_len(append_buf));
124 : 44652 : }
125 : :
126 : 7308783 : static inline void buf_append_char(Buf *buf, uint8_t c) {
127 : 7308783 : assert(buf->list.length);
128 : 7308783 : buf_append_mem(buf, (const char *)&c, 1);
129 : 7308783 : }
130 : :
131 : : void buf_appendf(Buf *buf, const char *format, ...)
132 : : ATTRIBUTE_PRINTF(2, 3);
133 : :
134 : 11270545 : static inline bool buf_eql_mem(Buf *buf, const char *mem, size_t mem_len) {
135 : 11270545 : assert(buf->list.length);
136 : 11270545 : return mem_eql_mem(buf_ptr(buf), buf_len(buf), mem, mem_len);
137 : : }
138 : :
139 : 62 : static inline bool buf_eql_mem_ignore_case(Buf *buf, const char *mem, size_t mem_len) {
140 : 62 : assert(buf->list.length);
141 : 62 : return mem_eql_mem_ignore_case(buf_ptr(buf), buf_len(buf), mem, mem_len);
142 : : }
143 : :
144 : 1638349 : static inline bool buf_eql_str(Buf *buf, const char *str) {
145 : 1638349 : assert(buf->list.length);
146 : 1638349 : return buf_eql_mem(buf, str, strlen(str));
147 : : }
148 : :
149 : 62 : static inline bool buf_eql_str_ignore_case(Buf *buf, const char *str) {
150 : 62 : assert(buf->list.length);
151 : 62 : return buf_eql_mem_ignore_case(buf, str, strlen(str));
152 : : }
153 : :
154 : 3452 : static inline bool buf_starts_with_mem(Buf *buf, const char *mem, size_t mem_len) {
155 [ - + ]: 3452 : if (buf_len(buf) < mem_len) {
156 : 0 : return false;
157 : : }
158 : 3452 : return memcmp(buf_ptr(buf), mem, mem_len) == 0;
159 : : }
160 : :
161 : 3426 : static inline bool buf_starts_with_buf(Buf *buf, Buf *sub) {
162 : 3426 : return buf_starts_with_mem(buf, buf_ptr(sub), buf_len(sub));
163 : : }
164 : :
165 : 26 : static inline bool buf_starts_with_str(Buf *buf, const char *str) {
166 : 26 : return buf_starts_with_mem(buf, str, strlen(str));
167 : : }
168 : :
169 : 227 : static inline bool buf_ends_with_mem(Buf *buf, const char *mem, size_t mem_len) {
170 [ - + ]: 227 : if (buf_len(buf) < mem_len) {
171 : 0 : return false;
172 : : }
173 : 227 : return memcmp(buf_ptr(buf) + buf_len(buf) - mem_len, mem, mem_len) == 0;
174 : : }
175 : :
176 : 227 : static inline bool buf_ends_with_str(Buf *buf, const char *str) {
177 : 227 : return buf_ends_with_mem(buf, str, strlen(str));
178 : : }
179 : :
180 : : bool buf_eql_buf(Buf *buf, Buf *other);
181 : : uint32_t buf_hash(Buf *buf);
182 : :
183 : 0 : static inline void buf_upcase(Buf *buf) {
184 [ # # ]: 0 : for (size_t i = 0; i < buf_len(buf); i += 1) {
185 : 0 : buf_ptr(buf)[i] = (char)toupper(buf_ptr(buf)[i]);
186 : : }
187 : 0 : }
188 : :
189 : 9673 : static inline Slice<uint8_t> buf_to_slice(Buf *buf) {
190 : 9673 : return Slice<uint8_t>{reinterpret_cast<uint8_t*>(buf_ptr(buf)), buf_len(buf)};
191 : : }
192 : :
193 : 1910 : static inline void buf_replace(Buf* buf, char from, char to) {
194 : 1910 : const size_t count = buf_len(buf);
195 : 1910 : char* ptr = buf_ptr(buf);
196 [ + + ]: 31926 : for (size_t i = 0; i < count; ++i) {
197 : 30016 : char& l = ptr[i];
198 [ + + ]: 30016 : if (l == from)
199 : 1904 : l = to;
200 : : }
201 : 1910 : }
202 : :
203 : :
204 : : #endif
|