|
| 1 | +#include <algorithm> |
| 2 | +#include <string_view> |
| 3 | +#include <vector> |
| 4 | + |
| 5 | +#pragma clang diagnostic push |
| 6 | +#pragma clang diagnostic ignored "-Winvalid-offsetof" |
| 7 | +#include "js/Utility.h" |
| 8 | +#pragma clang diagnostic pop |
| 9 | + |
1 | 10 | #include "xqd_world_adapter.h"
|
2 | 11 |
|
3 | 12 | #ifndef COMPONENT
|
@@ -176,50 +185,63 @@ bool xqd_fastly_http_req_new(fastly_request_handle_t *ret, fastly_error_t *err)
|
176 | 185 |
|
177 | 186 | bool xqd_fastly_http_req_header_names_get(fastly_request_handle_t h, fastly_list_string_t *ret,
|
178 | 187 | fastly_error_t *err) {
|
179 |
| - size_t str_max = LIST_ALLOC_SIZE; |
180 |
| - |
181 |
| - xqd_world_string_t *strs = |
182 |
| - static_cast<xqd_world_string_t *>(cabi_malloc(str_max * sizeof(xqd_world_string_t), 1)); |
183 |
| - size_t str_cnt = 0; |
184 |
| - size_t nwritten; |
185 |
| - char *buf = static_cast<char *>(cabi_malloc(HOSTCALL_BUFFER_LEN, 1)); |
186 |
| - uint32_t cursor = 0; |
187 |
| - int64_t next_cursor = 0; |
188 |
| - while (true) { |
189 |
| - if (!convert_result( |
190 |
| - xqd_req_header_names_get(h, buf, HEADER_MAX_LEN, cursor, &next_cursor, &nwritten), |
191 |
| - err)) { |
192 |
| - cabi_free(strs); |
193 |
| - cabi_free(buf); |
194 |
| - return false; |
| 188 | + struct Chunk { |
| 189 | + JS::UniqueChars buffer; |
| 190 | + size_t length; |
| 191 | + |
| 192 | + static Chunk make(std::string_view data) { |
| 193 | + Chunk res{JS::UniqueChars{static_cast<char *>(cabi_malloc(data.size(), 1))}, data.size()}; |
| 194 | + std::copy(data.begin(), data.end(), res.buffer.get()); |
| 195 | + return res; |
195 | 196 | }
|
196 |
| - if (nwritten == 0) |
197 |
| - break; |
198 |
| - uint32_t offset = 0; |
199 |
| - for (size_t i = 0; i < nwritten; i++) { |
200 |
| - if (buf[i] != '\0') |
201 |
| - continue; |
202 |
| - if (str_cnt == str_max) { |
203 |
| - strs = static_cast<xqd_world_string_t *>( |
204 |
| - cabi_realloc(strs, str_max * sizeof(xqd_world_string_t), 1, |
205 |
| - (str_max + LIST_ALLOC_SIZE) * sizeof(xqd_world_string_t))); |
206 |
| - str_max += LIST_ALLOC_SIZE; |
| 197 | + }; |
| 198 | + |
| 199 | + std::vector<Chunk> chunks; |
| 200 | + { |
| 201 | + JS::UniqueChars buf{static_cast<char *>(cabi_malloc(HOSTCALL_BUFFER_LEN, 1))}; |
| 202 | + uint32_t cursor = 0; |
| 203 | + while (true) { |
| 204 | + size_t length = 0; |
| 205 | + int64_t ending_cursor = 0; |
| 206 | + auto res = |
| 207 | + xqd_req_header_names_get(h, buf.get(), HEADER_MAX_LEN, cursor, &ending_cursor, &length); |
| 208 | + if (!convert_result(res, err)) { |
| 209 | + return false; |
207 | 210 | }
|
208 |
| - strs[str_cnt].ptr = static_cast<char *>(cabi_malloc(i - offset + 1, 1)); |
209 |
| - strs[str_cnt].len = i - offset; |
210 |
| - memcpy(strs[str_cnt].ptr, buf + offset, i - offset + 1); |
211 |
| - offset = i + 1; |
212 |
| - str_cnt++; |
| 211 | + |
| 212 | + if (length == 0) { |
| 213 | + break; |
| 214 | + } |
| 215 | + |
| 216 | + std::string_view result{buf.get(), length}; |
| 217 | + while (!result.empty()) { |
| 218 | + auto end = result.find('\0'); |
| 219 | + chunks.emplace_back(Chunk::make(result.substr(0, end))); |
| 220 | + if (end == result.npos) { |
| 221 | + break; |
| 222 | + } |
| 223 | + |
| 224 | + result = result.substr(end + 1); |
| 225 | + } |
| 226 | + |
| 227 | + if (ending_cursor < 0) { |
| 228 | + break; |
| 229 | + } |
| 230 | + |
| 231 | + cursor = ending_cursor; |
213 | 232 | }
|
214 |
| - if (next_cursor < 0) |
215 |
| - break; |
216 |
| - cursor = (uint32_t)next_cursor; |
217 | 233 | }
|
218 |
| - cabi_free(buf); |
219 |
| - strs = static_cast<xqd_world_string_t *>(cabi_realloc(strs, str_max * sizeof(xqd_world_string_t), |
220 |
| - 1, str_cnt * sizeof(xqd_world_string_t))); |
221 |
| - ret->ptr = strs; |
222 |
| - ret->len = str_cnt; |
| 234 | + |
| 235 | + ret->len = chunks.size(); |
| 236 | + ret->ptr = |
| 237 | + static_cast<xqd_world_string_t *>(cabi_malloc(chunks.size() * sizeof(xqd_world_string_t), 1)); |
| 238 | + auto *next = ret->ptr; |
| 239 | + for (auto &chunk : chunks) { |
| 240 | + next->len = chunk.length; |
| 241 | + next->ptr = chunk.buffer.release(); |
| 242 | + ++next; |
| 243 | + } |
| 244 | + |
223 | 245 | return true;
|
224 | 246 | }
|
225 | 247 |
|
|
0 commit comments